From 0976cd80b2b12436128cb4ce3af1d8240db7a0c6 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Wed, 12 Aug 2026 10:06:42 +0300 Subject: [PATCH 1/2] More concise matches on `FnKind`, some renamings --- compiler/rustc_hir_analysis/src/delegation.rs | 180 +++++++++--------- 1 file changed, 85 insertions(+), 95 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index ab34246d9716e..54bbbe4a79aef 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -2,6 +2,8 @@ //! //! For more information about delegation design, see the tracking issue #118212. +use std::ops::Not; + use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -71,22 +73,23 @@ enum SelfPositionKind { None, } -fn create_self_position_kind( +fn create_self_param_position_kind( tcx: TyCtxt<'_>, - delegation_id: LocalDefId, + def_id: LocalDefId, sig_id: DefId, ) -> SelfPositionKind { - match (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id)) { - (FnKind::AssocInherentImpl, FnKind::AssocTrait) - | (FnKind::AssocTraitImpl, FnKind::AssocTrait) - | (FnKind::AssocTrait, FnKind::AssocTrait) - | (FnKind::AssocTrait, FnKind::Free) => SelfPositionKind::Zero, - + match fn_kinds(tcx, def_id, sig_id) { (FnKind::Free, FnKind::AssocTrait) => { - let kind = tcx.hir_delegation_info(delegation_id).self_ty_propagation_kind; + let kind = tcx.hir_delegation_info(def_id).self_ty_propagation_kind; SelfPositionKind::AfterLifetimes(kind) } + (_, FnKind::AssocTraitImpl) => unreachable!(), + + (_, FnKind::AssocTrait) | (FnKind::AssocTrait, _) => SelfPositionKind::Zero, + + (FnKind::AssocTraitImpl, _) => unreachable!(), + _ => SelfPositionKind::None, } } @@ -116,6 +119,17 @@ fn fn_kind<'tcx>(tcx: TyCtxt<'tcx>, def_id: impl Into) -> FnKind { } } +fn fn_kinds<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, sig_id: DefId) -> (FnKind, FnKind) { + let kinds = (fn_kind(tcx, def_id), fn_kind(tcx, sig_id)); + + // For trait impl's `sig_id` is always equal to the corresponding trait method. + assert!(matches!(kinds, (_, FnKind::AssocTraitImpl)).not()); + // Delegation to inherent impls is not yet supported. + assert!(matches!(kinds, (_, FnKind::AssocInherentImpl)).not()); + + kinds +} + /// Given the current context(caller and callee `FnKind`), it specifies /// the policy of predicates and generic parameters inheritance. #[derive(Clone, Copy, Debug, PartialEq)] @@ -152,7 +166,7 @@ fn create_mapping<'tcx>( ) -> FxHashMap { let mut mapping: FxHashMap = Default::default(); - let self_pos_kind = create_self_position_kind(tcx, def_id, sig_id); + let self_pos_kind = create_self_param_position_kind(tcx, def_id, sig_id); let is_self_at_zero = matches!(self_pos_kind, SelfPositionKind::Zero); // Is self at zero? If so insert mapping, self in sig parent is always at 0. @@ -215,30 +229,24 @@ fn create_mapping<'tcx>( fn get_delegation_parent_args_count_without_self<'tcx>( tcx: TyCtxt<'tcx>, - delegation_id: LocalDefId, + def_id: LocalDefId, sig_id: DefId, ) -> usize { - let delegation_parent_args_count = tcx.generics_of(delegation_id).parent_count; + let kinds @ (def_kind, _) = fn_kinds(tcx, def_id, sig_id); - match (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id)) { - (FnKind::Free, FnKind::Free) - | (FnKind::Free, FnKind::AssocTrait) - | (FnKind::AssocTraitImpl, FnKind::AssocTrait) => 0, + match kinds { + (FnKind::AssocTraitImpl, FnKind::AssocTrait) => 0, - (FnKind::AssocInherentImpl, FnKind::Free) - | (FnKind::AssocInherentImpl, FnKind::AssocTrait) => { - delegation_parent_args_count /* No Self in AssocInherentImpl */ - } + (FnKind::AssocTraitImpl, _) | (_, FnKind::AssocTraitImpl) => unreachable!(), - (FnKind::AssocTrait, FnKind::Free) | (FnKind::AssocTrait, FnKind::AssocTrait) => { - delegation_parent_args_count - 1 /* Without Self */ - } + (FnKind::Free, _) => 0, - // For trait impl's `sig_id` is always equal to the corresponding trait method. - // For inherent methods delegation is not yet supported. - (FnKind::AssocTraitImpl, _) - | (_, FnKind::AssocTraitImpl) - | (_, FnKind::AssocInherentImpl) => unreachable!(), + (_, _) => { + let delegation_parent_args_count = tcx.generics_of(def_id).parent_count; + let has_self = def_kind == FnKind::AssocTrait; + + delegation_parent_args_count - usize::from(has_self) + } } } @@ -247,75 +255,57 @@ fn get_parent_and_inheritance_kind<'tcx>( def_id: LocalDefId, sig_id: DefId, ) -> (Option, InheritanceKind) { - match (fn_kind(tcx, def_id), fn_kind(tcx, sig_id)) { - (FnKind::Free, FnKind::Free) | (FnKind::Free, FnKind::AssocTrait) => { - (None, InheritanceKind::WithParent(true)) - } + let kinds @ (_, sig_kind) = fn_kinds(tcx, def_id, sig_id); + match kinds { (FnKind::AssocTraitImpl, FnKind::AssocTrait) => { (Some(tcx.parent(def_id.to_def_id())), InheritanceKind::Own) } - (FnKind::AssocInherentImpl, FnKind::AssocTrait) - | (FnKind::AssocTrait, FnKind::AssocTrait) - | (FnKind::AssocInherentImpl, FnKind::Free) - | (FnKind::AssocTrait, FnKind::Free) => { - (Some(tcx.parent(def_id.to_def_id())), InheritanceKind::WithParent(false)) + (FnKind::AssocTraitImpl, _) | (_, FnKind::AssocTraitImpl) => unreachable!(), + + (FnKind::Free, _) => { + let copy_self_clauses = sig_kind == FnKind::AssocTrait; + (None, InheritanceKind::WithParent(copy_self_clauses)) } - // For trait impl's `sig_id` is always equal to the corresponding trait method. - // For inherent methods delegation is not yet supported. - (FnKind::AssocTraitImpl, _) - | (_, FnKind::AssocTraitImpl) - | (_, FnKind::AssocInherentImpl) => unreachable!(), + (_, _) => (Some(tcx.parent(def_id.to_def_id())), InheritanceKind::WithParent(false)), } } -fn get_delegation_self_ty<'tcx>(tcx: TyCtxt<'tcx>, delegation_id: LocalDefId) -> Option> { - let sig_id = tcx.hir_opt_delegation_sig_id(delegation_id).expect("Delegation must have sig_id"); - let (caller_kind, callee_kind) = (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id)); +fn get_delegation_self_ty<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Option> { + let sig_id = tcx.hir_opt_delegation_sig_id(def_id).expect("processing delegation"); + let (caller_kind, callee_kind) = fn_kinds(tcx, def_id, sig_id); match (caller_kind, callee_kind) { - (FnKind::Free, FnKind::AssocTrait) - | (FnKind::AssocInherentImpl, FnKind::Free) - | (FnKind::Free, FnKind::Free) - | (FnKind::AssocTrait, FnKind::Free) - | (FnKind::AssocTrait, FnKind::AssocTrait) => { - match create_self_position_kind(tcx, delegation_id, sig_id) { - SelfPositionKind::None => None, - SelfPositionKind::AfterLifetimes(propagation_kind) => { - Some(match propagation_kind { - Some(kind) => match kind { - DelegationSelfTyPropagationKind::SelfTy(self_ty_id) => { - let ctx = ItemCtxt::new(tcx, delegation_id); - ctx.lower_ty(tcx.hir_node(self_ty_id).expect_ty()) - } - DelegationSelfTyPropagationKind::SelfParam => { - let index = tcx.generics_of(delegation_id).own_counts().lifetimes; - Ty::new_param(tcx, index as u32, kw::SelfUpper) - } - }, - None => Ty::new_error_with_message( - tcx, - tcx.def_span(delegation_id), - "self propagation kind must be specified for `AfterLifetimes` variant", - ), - }) - } - SelfPositionKind::Zero => Some(Ty::new_param(tcx, 0, kw::SelfUpper)), - } + (FnKind::AssocTraitImpl, FnKind::AssocTrait) | (FnKind::AssocInherentImpl, _) => { + Some(tcx.type_of(tcx.local_parent(def_id)).instantiate_identity().skip_norm_wip()) } - (FnKind::AssocTraitImpl, FnKind::AssocTrait) - | (FnKind::AssocInherentImpl, FnKind::AssocTrait) => Some( - tcx.type_of(tcx.local_parent(delegation_id)).instantiate_identity().skip_norm_wip(), - ), - // For trait impl's `sig_id` is always equal to the corresponding trait method. - // For inherent methods delegation is not yet supported. - (FnKind::AssocTraitImpl, _) - | (_, FnKind::AssocTraitImpl) - | (_, FnKind::AssocInherentImpl) => unreachable!(), + (FnKind::AssocTraitImpl, _) | (_, FnKind::AssocTraitImpl) => unreachable!(), + + (_, _) => match create_self_param_position_kind(tcx, def_id, sig_id) { + SelfPositionKind::None => None, + SelfPositionKind::AfterLifetimes(propagation_kind) => Some(match propagation_kind { + Some(kind) => match kind { + DelegationSelfTyPropagationKind::SelfTy(self_ty_id) => { + let ctx = ItemCtxt::new(tcx, def_id); + ctx.lower_ty(tcx.hir_node(self_ty_id).expect_ty()) + } + DelegationSelfTyPropagationKind::SelfParam => { + let index = tcx.generics_of(def_id).own_counts().lifetimes; + Ty::new_param(tcx, index as u32, kw::SelfUpper) + } + }, + None => Ty::new_error_with_message( + tcx, + tcx.def_span(def_id), + "self propagation kind must be specified for `AfterLifetimes` variant", + ), + }), + SelfPositionKind::Zero => Some(Ty::new_param(tcx, 0, kw::SelfUpper)), + }, } } @@ -337,12 +327,12 @@ fn get_delegation_self_ty<'tcx>(tcx: TyCtxt<'tcx>, delegation_id: LocalDefId) -> fn create_generic_args<'tcx>( tcx: TyCtxt<'tcx>, sig_id: DefId, - delegation_id: LocalDefId, + def_id: LocalDefId, mut parent_args: &[ty::GenericArg<'tcx>], mut child_args: &[ty::GenericArg<'tcx>], ) -> (Vec>, &'tcx [ty::GenericArg<'tcx>]) { - let delegation_generics = tcx.generics_of(delegation_id); - let delegation_args = ty::GenericArgs::identity_for_item(tcx, delegation_id); + let delegation_generics = tcx.generics_of(def_id); + let delegation_args = ty::GenericArgs::identity_for_item(tcx, def_id); let real_args_count = delegation_args.len() - delegation_generics.own_synthetic_params_count(); let synth_args = &delegation_args[real_args_count..]; @@ -352,12 +342,12 @@ fn create_generic_args<'tcx>( let delegation_args = &delegation_args[delegation_generics.parent_count..]; - let kinds = (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id)); + let kinds = fn_kinds(tcx, def_id, sig_id); if matches!(kinds, (FnKind::AssocTraitImpl, FnKind::AssocTrait)) { // Special case, as user specifies Trait args in trait impl header, we want to treat // them as parent args. We always generate a function whose generics match // child generics in trait. - let parent = tcx.local_parent(delegation_id); + let parent = tcx.local_parent(def_id); parent_args = tcx.impl_trait_header(parent).trait_ref.instantiate_identity().skip_norm_wip().args; @@ -368,7 +358,7 @@ fn create_generic_args<'tcx>( delegation_parent_args = &[]; } - let self_type = get_delegation_self_ty(tcx, delegation_id).map(|t| t.into()); + let self_type = get_delegation_self_ty(tcx, def_id).map(ty::GenericArg::from); // Remove `Self` from parent args (it is always at the `0th` index) as it is // added manually. @@ -377,7 +367,7 @@ fn create_generic_args<'tcx>( } let (zero_self, after_lifetimes_self) = - match create_self_position_kind(tcx, delegation_id, sig_id) { + match create_self_param_position_kind(tcx, def_id, sig_id) { SelfPositionKind::AfterLifetimes(_) => { assert!(self_type.is_some()); (None, self_type) @@ -505,7 +495,7 @@ pub(crate) fn inherit_clauses_for_delegation_item<'tcx>( let (parent_args, child_args) = tcx.delegation_user_specified_args(def_id); let (folder, args) = create_folder_and_args(tcx, def_id, sig_id, parent_args, child_args); - let self_pos_kind = create_self_position_kind(tcx, def_id, sig_id); + let self_pos_kind = create_self_param_position_kind(tcx, def_id, sig_id); let filter_self_clauses = matches!( self_pos_kind, SelfPositionKind::AfterLifetimes(Some(DelegationSelfTyPropagationKind::SelfTy(..))) @@ -584,7 +574,6 @@ pub(crate) fn inherit_sig_for_delegation_item<'tcx>( ) -> &'tcx [Ty<'tcx>] { let sig_id = tcx.hir_opt_delegation_sig_id(def_id).expect("Delegation must have sig_id"); let caller_sig = tcx.fn_sig(sig_id); - if let Err(err) = check_constraints(tcx, def_id, sig_id) { let sig_len = caller_sig.instantiate_identity().skip_binder().inputs().len() + 1; let err_type = Ty::new_error(tcx, err); @@ -606,23 +595,24 @@ pub(crate) fn inherit_sig_for_delegation_item<'tcx>( // we want to extract [Self, 'static, i32, 1] for parent and [A, B] for child. pub(crate) fn delegation_user_specified_args<'tcx>( tcx: TyCtxt<'tcx>, - delegation_id: LocalDefId, + def_id: LocalDefId, ) -> (&'tcx [ty::GenericArg<'tcx>], &'tcx [ty::GenericArg<'tcx>]) { - let info = tcx.hir_delegation_info(delegation_id); + let info = tcx.hir_delegation_info(def_id); let get_segment = |hir_id| -> Option<(&'tcx PathSegment<'tcx>, DefId)> { let segment = tcx.hir_node(hir_id).expect_path_segment(); segment.res.opt_def_id().map(|def_id| (segment, def_id)) }; - let ctx = ItemCtxt::new_for_delegation(tcx, delegation_id); + let ctx = ItemCtxt::new_for_delegation(tcx, def_id); let lowerer = ctx.lowerer(); let parent_args = info .parent_seg_id_for_sig .and_then(get_segment) .filter(|(_, def_id)| matches!(tcx.def_kind(*def_id), DefKind::Trait)) .map(|(segment, def_id)| { - let self_ty = get_delegation_self_ty(tcx, delegation_id); + let self_param = Ty::new_param(tcx, 0, kw::SelfUpper); + let self_ty = (tcx.def_kind(def_id) == DefKind::Trait).then_some(self_param); lowerer .lower_generic_args_of_path(segment.ident.span, def_id, &[], segment, self_ty) From e680d295c812040ceb986605f7ab82d41d682bb1 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Wed, 12 Aug 2026 10:08:19 +0300 Subject: [PATCH 2/2] Move most of utility functions to extensions --- compiler/rustc_hir_analysis/src/delegation.rs | 270 +++++++++--------- 1 file changed, 138 insertions(+), 132 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index 54bbbe4a79aef..ca8805fb2e05a 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -8,6 +8,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{DelegationSelfTyPropagationKind, PathSegment}; +use rustc_macros::extension; use rustc_middle::ty::{ self, EarlyBinder, RegionExt, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, @@ -73,27 +74,6 @@ enum SelfPositionKind { None, } -fn create_self_param_position_kind( - tcx: TyCtxt<'_>, - def_id: LocalDefId, - sig_id: DefId, -) -> SelfPositionKind { - match fn_kinds(tcx, def_id, sig_id) { - (FnKind::Free, FnKind::AssocTrait) => { - let kind = tcx.hir_delegation_info(def_id).self_ty_propagation_kind; - SelfPositionKind::AfterLifetimes(kind) - } - - (_, FnKind::AssocTraitImpl) => unreachable!(), - - (_, FnKind::AssocTrait) | (FnKind::AssocTrait, _) => SelfPositionKind::Zero, - - (FnKind::AssocTraitImpl, _) => unreachable!(), - - _ => SelfPositionKind::None, - } -} - #[derive(Clone, Copy, Debug, PartialEq)] enum FnKind { Free, @@ -102,32 +82,140 @@ enum FnKind { AssocTraitImpl, } -fn fn_kind<'tcx>(tcx: TyCtxt<'tcx>, def_id: impl Into) -> FnKind { - let def_id = def_id.into(); - - match tcx.def_kind(def_id) { - DefKind::Fn => FnKind::Free, - DefKind::AssocFn => match tcx.def_kind(tcx.parent(def_id)) { - DefKind::Trait => FnKind::AssocTrait, - DefKind::Impl { of_trait } => match of_trait { - true => FnKind::AssocTraitImpl, - false => FnKind::AssocInherentImpl, +#[extension(trait DelegationTyCtxtExt<'tcx>)] +impl<'tcx> TyCtxt<'tcx> { + fn fn_kind(self, def_id: impl Into) -> FnKind { + let def_id = def_id.into(); + + match self.def_kind(def_id) { + DefKind::Fn => FnKind::Free, + DefKind::AssocFn => match self.def_kind(self.parent(def_id)) { + DefKind::Trait => FnKind::AssocTrait, + DefKind::Impl { of_trait } => match of_trait { + true => FnKind::AssocTraitImpl, + false => FnKind::AssocInherentImpl, + }, + _ => unreachable!("associated function can only be in trait or impl"), }, - _ => unreachable!("associated function can only be in trait or impl"), - }, - _ => unreachable!("delegation/signature can be either free or associated function"), + _ => unreachable!("delegation/signature can be either free or associated function"), + } } -} -fn fn_kinds<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, sig_id: DefId) -> (FnKind, FnKind) { - let kinds = (fn_kind(tcx, def_id), fn_kind(tcx, sig_id)); + fn fn_kinds(self, def_id: LocalDefId, sig_id: DefId) -> (FnKind, FnKind) { + let kinds = (self.fn_kind(def_id), self.fn_kind(sig_id)); + + // For trait impl's `sig_id` is always equal to the corresponding trait method. + assert!(matches!(kinds, (_, FnKind::AssocTraitImpl)).not()); + // Delegation to inherent impls is not yet supported. + assert!(matches!(kinds, (_, FnKind::AssocInherentImpl)).not()); + + kinds + } + + fn get_delegation_parent_args_count_without_self( + self, + def_id: LocalDefId, + sig_id: DefId, + ) -> usize { + let kinds @ (def_kind, _) = self.fn_kinds(def_id, sig_id); + + match kinds { + (FnKind::AssocTraitImpl, FnKind::AssocTrait) => 0, + + (FnKind::AssocTraitImpl, _) | (_, FnKind::AssocTraitImpl) => unreachable!(), + + (FnKind::Free, _) => 0, + + (_, _) => { + let delegation_parent_args_count = self.generics_of(def_id).parent_count; + let has_self = def_kind == FnKind::AssocTrait; + + delegation_parent_args_count - usize::from(has_self) + } + } + } + + fn get_parent_and_inheritance_kind( + self, + def_id: LocalDefId, + sig_id: DefId, + ) -> (Option, InheritanceKind) { + let kinds @ (_, sig_kind) = self.fn_kinds(def_id, sig_id); + + match kinds { + (FnKind::AssocTraitImpl, FnKind::AssocTrait) => { + (Some(self.parent(def_id.to_def_id())), InheritanceKind::Own) + } + + (FnKind::AssocTraitImpl, _) | (_, FnKind::AssocTraitImpl) => unreachable!(), + + (FnKind::Free, _) => { + let copy_self_clauses = sig_kind == FnKind::AssocTrait; + (None, InheritanceKind::WithParent(copy_self_clauses)) + } + + (_, _) => (Some(self.parent(def_id.to_def_id())), InheritanceKind::WithParent(false)), + } + } + + fn create_self_param_position_kind( + self, + def_id: LocalDefId, + sig_id: DefId, + ) -> SelfPositionKind { + match self.fn_kinds(def_id, sig_id) { + (FnKind::Free, FnKind::AssocTrait) => { + let kind = self.hir_delegation_info(def_id).self_ty_propagation_kind; + SelfPositionKind::AfterLifetimes(kind) + } + + (_, FnKind::AssocTraitImpl) => unreachable!(), + + (_, FnKind::AssocTrait) | (FnKind::AssocTrait, _) => SelfPositionKind::Zero, + + (FnKind::AssocTraitImpl, _) => unreachable!(), + + _ => SelfPositionKind::None, + } + } + + fn get_delegation_self_ty(self, def_id: LocalDefId) -> Option> { + let sig_id = self.hir_opt_delegation_sig_id(def_id).expect("processing delegation"); + let (caller_kind, callee_kind) = self.fn_kinds(def_id, sig_id); - // For trait impl's `sig_id` is always equal to the corresponding trait method. - assert!(matches!(kinds, (_, FnKind::AssocTraitImpl)).not()); - // Delegation to inherent impls is not yet supported. - assert!(matches!(kinds, (_, FnKind::AssocInherentImpl)).not()); + match (caller_kind, callee_kind) { + (FnKind::AssocTraitImpl, FnKind::AssocTrait) | (FnKind::AssocInherentImpl, _) => { + Some(self.type_of(self.local_parent(def_id)).instantiate_identity().skip_norm_wip()) + } - kinds + // For trait impl's `sig_id` is always equal to the corresponding trait method. + (FnKind::AssocTraitImpl, _) | (_, FnKind::AssocTraitImpl) => unreachable!(), + + (_, _) => match self.create_self_param_position_kind(def_id, sig_id) { + SelfPositionKind::None => None, + SelfPositionKind::AfterLifetimes(propagation_kind) => { + Some(match propagation_kind { + Some(kind) => match kind { + DelegationSelfTyPropagationKind::SelfTy(self_ty_id) => { + let ctx = ItemCtxt::new(self, def_id); + ctx.lower_ty(self.hir_node(self_ty_id).expect_ty()) + } + DelegationSelfTyPropagationKind::SelfParam => { + let index = self.generics_of(def_id).own_counts().lifetimes; + Ty::new_param(self, index as u32, kw::SelfUpper) + } + }, + None => Ty::new_error_with_message( + self, + self.def_span(def_id), + "self propagation kind must be specified for `AfterLifetimes` variant", + ), + }) + } + SelfPositionKind::Zero => Some(Ty::new_param(self, 0, kw::SelfUpper)), + }, + } + } } /// Given the current context(caller and callee `FnKind`), it specifies @@ -166,7 +254,7 @@ fn create_mapping<'tcx>( ) -> FxHashMap { let mut mapping: FxHashMap = Default::default(); - let self_pos_kind = create_self_param_position_kind(tcx, def_id, sig_id); + let self_pos_kind = tcx.create_self_param_position_kind(def_id, sig_id); let is_self_at_zero = matches!(self_pos_kind, SelfPositionKind::Zero); // Is self at zero? If so insert mapping, self in sig parent is always at 0. @@ -177,10 +265,10 @@ fn create_mapping<'tcx>( let mut args_index = 0; args_index += is_self_at_zero as usize; - args_index += get_delegation_parent_args_count_without_self(tcx, def_id, sig_id); + args_index += tcx.get_delegation_parent_args_count_without_self(def_id, sig_id); let sig_generics = tcx.generics_of(sig_id); - let process_sig_parent_generics = matches!(fn_kind(tcx, sig_id), FnKind::AssocTrait); + let process_sig_parent_generics = matches!(tcx.fn_kind(sig_id), FnKind::AssocTrait); if process_sig_parent_generics { for i in (sig_generics.has_self as usize)..sig_generics.parent_count { @@ -227,88 +315,6 @@ fn create_mapping<'tcx>( mapping } -fn get_delegation_parent_args_count_without_self<'tcx>( - tcx: TyCtxt<'tcx>, - def_id: LocalDefId, - sig_id: DefId, -) -> usize { - let kinds @ (def_kind, _) = fn_kinds(tcx, def_id, sig_id); - - match kinds { - (FnKind::AssocTraitImpl, FnKind::AssocTrait) => 0, - - (FnKind::AssocTraitImpl, _) | (_, FnKind::AssocTraitImpl) => unreachable!(), - - (FnKind::Free, _) => 0, - - (_, _) => { - let delegation_parent_args_count = tcx.generics_of(def_id).parent_count; - let has_self = def_kind == FnKind::AssocTrait; - - delegation_parent_args_count - usize::from(has_self) - } - } -} - -fn get_parent_and_inheritance_kind<'tcx>( - tcx: TyCtxt<'tcx>, - def_id: LocalDefId, - sig_id: DefId, -) -> (Option, InheritanceKind) { - let kinds @ (_, sig_kind) = fn_kinds(tcx, def_id, sig_id); - - match kinds { - (FnKind::AssocTraitImpl, FnKind::AssocTrait) => { - (Some(tcx.parent(def_id.to_def_id())), InheritanceKind::Own) - } - - (FnKind::AssocTraitImpl, _) | (_, FnKind::AssocTraitImpl) => unreachable!(), - - (FnKind::Free, _) => { - let copy_self_clauses = sig_kind == FnKind::AssocTrait; - (None, InheritanceKind::WithParent(copy_self_clauses)) - } - - (_, _) => (Some(tcx.parent(def_id.to_def_id())), InheritanceKind::WithParent(false)), - } -} - -fn get_delegation_self_ty<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Option> { - let sig_id = tcx.hir_opt_delegation_sig_id(def_id).expect("processing delegation"); - let (caller_kind, callee_kind) = fn_kinds(tcx, def_id, sig_id); - - match (caller_kind, callee_kind) { - (FnKind::AssocTraitImpl, FnKind::AssocTrait) | (FnKind::AssocInherentImpl, _) => { - Some(tcx.type_of(tcx.local_parent(def_id)).instantiate_identity().skip_norm_wip()) - } - - // For trait impl's `sig_id` is always equal to the corresponding trait method. - (FnKind::AssocTraitImpl, _) | (_, FnKind::AssocTraitImpl) => unreachable!(), - - (_, _) => match create_self_param_position_kind(tcx, def_id, sig_id) { - SelfPositionKind::None => None, - SelfPositionKind::AfterLifetimes(propagation_kind) => Some(match propagation_kind { - Some(kind) => match kind { - DelegationSelfTyPropagationKind::SelfTy(self_ty_id) => { - let ctx = ItemCtxt::new(tcx, def_id); - ctx.lower_ty(tcx.hir_node(self_ty_id).expect_ty()) - } - DelegationSelfTyPropagationKind::SelfParam => { - let index = tcx.generics_of(def_id).own_counts().lifetimes; - Ty::new_param(tcx, index as u32, kw::SelfUpper) - } - }, - None => Ty::new_error_with_message( - tcx, - tcx.def_span(def_id), - "self propagation kind must be specified for `AfterLifetimes` variant", - ), - }), - SelfPositionKind::Zero => Some(Ty::new_param(tcx, 0, kw::SelfUpper)), - }, - } -} - /// Creates generic arguments for further delegation signature and predicates instantiation. /// Arguments can be user-specified (in this case they are in `parent_args` and `child_args`) /// or propagated. User can specify either both `parent_args` and `child_args`, one of them or none, @@ -342,7 +348,7 @@ fn create_generic_args<'tcx>( let delegation_args = &delegation_args[delegation_generics.parent_count..]; - let kinds = fn_kinds(tcx, def_id, sig_id); + let kinds = tcx.fn_kinds(def_id, sig_id); if matches!(kinds, (FnKind::AssocTraitImpl, FnKind::AssocTrait)) { // Special case, as user specifies Trait args in trait impl header, we want to treat // them as parent args. We always generate a function whose generics match @@ -358,7 +364,7 @@ fn create_generic_args<'tcx>( delegation_parent_args = &[]; } - let self_type = get_delegation_self_ty(tcx, def_id).map(ty::GenericArg::from); + let self_type = tcx.get_delegation_self_ty(def_id).map(ty::GenericArg::from); // Remove `Self` from parent args (it is always at the `0th` index) as it is // added manually. @@ -367,7 +373,7 @@ fn create_generic_args<'tcx>( } let (zero_self, after_lifetimes_self) = - match create_self_param_position_kind(tcx, def_id, sig_id) { + match tcx.create_self_param_position_kind(def_id, sig_id) { SelfPositionKind::AfterLifetimes(_) => { assert!(self_type.is_some()); (None, self_type) @@ -495,14 +501,14 @@ pub(crate) fn inherit_clauses_for_delegation_item<'tcx>( let (parent_args, child_args) = tcx.delegation_user_specified_args(def_id); let (folder, args) = create_folder_and_args(tcx, def_id, sig_id, parent_args, child_args); - let self_pos_kind = create_self_param_position_kind(tcx, def_id, sig_id); + let self_pos_kind = tcx.create_self_param_position_kind(def_id, sig_id); let filter_self_clauses = matches!( self_pos_kind, SelfPositionKind::AfterLifetimes(Some(DelegationSelfTyPropagationKind::SelfTy(..))) ); let collector = ClausesCollector { tcx, clauses: vec![], args, folder, filter_self_clauses }; - let (parent, inh_kind) = get_parent_and_inheritance_kind(tcx, def_id, sig_id); + let (parent, inh_kind) = tcx.get_parent_and_inheritance_kind(def_id, sig_id); // `explicit_clauses_of` is used here to avoid copying `Self: Trait` clause. // Note: `clauses_of` query can also add inferred outlives clauses, but that