diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 0044913721f1f..1690005c5d292 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -146,12 +146,10 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { let (param_count, c_variadic) = self.param_count(sig_id); - let mut generics = - self.lower_delegation_generics(delegation, sig_id, item_id, span); + let mut generics = self.lower_delegation_generics(delegation, sig_id, item_id); let body_id = self.lower_delegation_body( delegation, - item_id, is_method, param_count, &mut generics, @@ -166,10 +164,8 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { let generics = self.arena.alloc(hir::Generics { has_where_clause_predicates: false, - params: self.arena.alloc_from_iter(generics.all_params(item_id, span, self)), - predicates: self - .arena - .alloc_from_iter(generics.all_predicates(item_id, span, self)), + params: self.arena.alloc_from_iter(generics.all_params(span, self)), + predicates: self.arena.alloc_from_iter(generics.all_predicates(span, self)), span, where_clause_span: span, }); @@ -294,19 +290,22 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { let decl_param_count = param_count - c_variadic as usize; let inputs = self.arena.alloc_from_iter((0..decl_param_count).map(|arg| hir::Ty { hir_id: self.next_id(), - kind: hir::TyKind::InferDelegation(sig_id, hir::InferDelegationKind::Input(arg)), + kind: hir::TyKind::InferDelegation(hir::InferDelegation::Sig( + sig_id, + hir::InferDelegationSig::Input(arg), + )), span, })); let output = self.arena.alloc(hir::Ty { hir_id: self.next_id(), - kind: hir::TyKind::InferDelegation( + kind: hir::TyKind::InferDelegation(hir::InferDelegation::Sig( sig_id, - hir::InferDelegationKind::Output(self.arena.alloc(hir::DelegationGenerics { + hir::InferDelegationSig::Output(self.arena.alloc(hir::DelegationGenerics { child_args_segment_id: generics.child.args_segment_id, parent_args_segment_id: generics.parent.args_segment_id, })), - ), + )), span, }); @@ -399,7 +398,6 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { fn lower_delegation_body( &mut self, delegation: &Delegation, - item_id: NodeId, is_method: bool, param_count: usize, generics: &mut GenericsGenerationResults<'hir>, @@ -434,7 +432,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { args.push(arg); } - let final_expr = this.finalize_body_lowering(delegation, item_id, args, generics, span); + let final_expr = this.finalize_body_lowering(delegation, args, generics, span); (this.arena.alloc_from_iter(parameters), final_expr) }) @@ -471,7 +469,6 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { fn finalize_body_lowering( &mut self, delegation: &Delegation, - item_id: NodeId, args: Vec>, generics: &mut GenericsGenerationResults<'hir>, span: Span, @@ -501,7 +498,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { // FIXME(fn_delegation): proper support for parent generics propagation // in method call scenario. - let segment = self.process_segment(item_id, span, &segment, &mut generics.child, false); + let segment = self.process_segment(span, &segment, &mut generics.child, false); let segment = self.arena.alloc(segment); self.arena.alloc(hir::Expr { @@ -528,7 +525,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { new_path.segments = self.arena.alloc_from_iter( new_path.segments.iter().enumerate().map(|(idx, segment)| { let mut process_segment = |result, add_lifetimes| { - self.process_segment(item_id, span, segment, result, add_lifetimes) + self.process_segment(span, segment, result, add_lifetimes) }; if idx + 2 == len { @@ -544,8 +541,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { hir::QPath::Resolved(ty, self.arena.alloc(new_path)) } hir::QPath::TypeRelative(ty, segment) => { - let segment = - self.process_segment(item_id, span, segment, &mut generics.child, false); + let segment = self.process_segment(span, segment, &mut generics.child, false); hir::QPath::TypeRelative(ty, self.arena.alloc(segment)) } @@ -569,7 +565,6 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { fn process_segment( &mut self, - item_id: NodeId, span: Span, segment: &hir::PathSegment<'hir>, result: &mut GenericsGenerationResult<'hir>, @@ -580,11 +575,11 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { // The first condition is needed when there is SelfAndUserSpecified case, // we don't want to propagate generics params in this situation. let segment = if details.should_propagate - && let Some(args) = result - .generics - .into_hir_generics(self, item_id, span) - .into_generic_args(self, add_lifetimes, span) - { + && let Some(args) = result.generics.into_hir_generics(self, span).into_generic_args( + self, + add_lifetimes, + span, + ) { hir::PathSegment { args: Some(args), ..segment.clone() } } else { segment.clone() diff --git a/compiler/rustc_ast_lowering/src/delegation/generics.rs b/compiler/rustc_ast_lowering/src/delegation/generics.rs index d6d8819d8c474..5a0e53ba08c1d 100644 --- a/compiler/rustc_ast_lowering/src/delegation/generics.rs +++ b/compiler/rustc_ast_lowering/src/delegation/generics.rs @@ -5,10 +5,8 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty::GenericParamDefKind; use rustc_middle::{bug, ty}; -use rustc_span::sym::{self}; use rustc_span::symbol::kw; use rustc_span::{Ident, Span}; -use thin_vec::{ThinVec, thin_vec}; use crate::{LoweringContext, ResolverAstLoweringExt}; @@ -26,24 +24,23 @@ pub(super) enum DelegationGenerics { TraitImpl(Option, bool /* Has user-specified args */), } -/// Used for storing either AST generics or their lowered HIR version. Firstly we obtain -/// AST generics either from local function from AST index or from external function -/// through `tcx`. Next, at some point of generics processing we need to lower those -/// generics to HIR, for this purpose we use `into_hir_generics` that lowers AST generics -/// and replaces Ast variant with Hir. Such approach is useful as we can call this method +/// Used for storing either ty generics or their lowered HIR version. Firstly we obtain +/// ty generics. Next, at some point of generics processing we need to lower those +/// generics to HIR, for this purpose we use `into_hir_generics` that lowers ty generics +/// and replaces Ty variant with Hir. Such approach is useful as we can call this method /// at any time knowing that lowering will occur at most only once. Then, in order to obtain generic /// params or args we use `hir_generics_or_empty` or `into_generic_args` functions. -/// There also may be situations when we obtained AST generics but never lowered them to HIR, +/// There also may be situations when we obtained ty generics but never lowered them to HIR, /// meaning we did not propagate them and thus we do not need to generate generic params /// (i.e., method call scenarios), in such a case this approach helps /// a lot as if `into_hir_generics` will not be called then lowering will not happen. -pub(super) enum HirOrAstGenerics<'hir> { - Ast(DelegationGenerics), +pub(super) enum HirOrTyGenerics<'hir> { + Ty(DelegationGenerics>), Hir(DelegationGenerics<&'hir hir::Generics<'hir>>), } pub(super) struct GenericsGenerationResult<'hir> { - pub(super) generics: HirOrAstGenerics<'hir>, + pub(super) generics: HirOrTyGenerics<'hir>, pub(super) args_segment_id: Option, } @@ -78,35 +75,36 @@ impl DelegationGenerics { } } -impl<'hir> HirOrAstGenerics<'hir> { +impl<'hir> HirOrTyGenerics<'hir> { pub(super) fn into_hir_generics( &mut self, ctx: &mut LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'hir>>, - item_id: NodeId, span: Span, - ) -> &mut HirOrAstGenerics<'hir> { - if let HirOrAstGenerics::Ast(generics) = self { - let process_params = |generics: &mut Generics| { - ctx.lower_delegation_generic_params(item_id, span, &mut generics.params) + ) -> &mut HirOrTyGenerics<'hir> { + if let HirOrTyGenerics::Ty(params) = self { + let process_params = |generics: &[ty::GenericParamDef]| { + ctx.lower_delegation_generic_params(span, generics) }; - let hir_generics = match generics { + let hir_generics = match params { DelegationGenerics::UserSpecified => DelegationGenerics::UserSpecified, - DelegationGenerics::Default(generics) => { - DelegationGenerics::Default(generics.as_mut().map(process_params)) + DelegationGenerics::Default(params) => { + DelegationGenerics::Default(params.as_ref().map(|p| &p[..]).map(process_params)) } - DelegationGenerics::SelfAndUserSpecified(generics) => { - DelegationGenerics::SelfAndUserSpecified(generics.as_mut().map(process_params)) + DelegationGenerics::SelfAndUserSpecified(params) => { + DelegationGenerics::SelfAndUserSpecified( + params.as_ref().map(|p| &p[..]).map(process_params), + ) } - DelegationGenerics::TraitImpl(generics, user_specified) => { + DelegationGenerics::TraitImpl(params, user_specified) => { DelegationGenerics::TraitImpl( - generics.as_mut().map(process_params), + params.as_ref().map(|p| &p[..]).map(process_params), *user_specified, ) } }; - *self = HirOrAstGenerics::Hir(hir_generics); + *self = HirOrTyGenerics::Hir(hir_generics); } self @@ -114,8 +112,8 @@ impl<'hir> HirOrAstGenerics<'hir> { fn hir_generics_or_empty(&self) -> &'hir hir::Generics<'hir> { match self { - HirOrAstGenerics::Ast(_) => hir::Generics::empty(), - HirOrAstGenerics::Hir(hir_generics) => match hir_generics { + HirOrTyGenerics::Ty(_) => hir::Generics::empty(), + HirOrTyGenerics::Hir(hir_generics) => match hir_generics { DelegationGenerics::UserSpecified => hir::Generics::empty(), DelegationGenerics::Default(generics) | DelegationGenerics::SelfAndUserSpecified(generics) @@ -133,10 +131,10 @@ impl<'hir> HirOrAstGenerics<'hir> { span: Span, ) -> Option<&'hir hir::GenericArgs<'hir>> { match self { - HirOrAstGenerics::Ast(_) => { + HirOrTyGenerics::Ty(_) => { bug!("Attempting to get generic args before lowering to HIR") } - HirOrAstGenerics::Hir(hir_generics) => match hir_generics { + HirOrTyGenerics::Hir(hir_generics) => match hir_generics { DelegationGenerics::UserSpecified => None, DelegationGenerics::Default(generics) | DelegationGenerics::SelfAndUserSpecified(generics) @@ -149,25 +147,23 @@ impl<'hir> HirOrAstGenerics<'hir> { pub(super) fn args_propagation_details(&self) -> GenericArgsPropagationDetails { match self { - HirOrAstGenerics::Ast(ast_generics) => ast_generics.args_propagation_details(), - HirOrAstGenerics::Hir(hir_generics) => hir_generics.args_propagation_details(), + HirOrTyGenerics::Ty(ty_generics) => ty_generics.args_propagation_details(), + HirOrTyGenerics::Hir(hir_generics) => hir_generics.args_propagation_details(), } } } -impl<'a> GenericsGenerationResult<'a> { - fn new(generics: DelegationGenerics) -> GenericsGenerationResult<'a> { - GenericsGenerationResult { - generics: HirOrAstGenerics::Ast(generics), - args_segment_id: None, - } +impl<'hir> GenericsGenerationResult<'hir> { + fn new( + generics: DelegationGenerics>, + ) -> GenericsGenerationResult<'hir> { + GenericsGenerationResult { generics: HirOrTyGenerics::Ty(generics), args_segment_id: None } } } impl<'hir> GenericsGenerationResults<'hir> { pub(super) fn all_params( &mut self, - item_id: NodeId, span: Span, ctx: &mut LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'hir>>, ) -> impl Iterator> { @@ -176,19 +172,12 @@ impl<'hir> GenericsGenerationResults<'hir> { // method call will be supported (if HIR generics were not obtained // then it means that we did not propagated them, thus we do not need // to generate params). - let parent = self - .parent - .generics - .into_hir_generics(ctx, item_id, span) - .hir_generics_or_empty() - .params; - - let child = self - .child - .generics - .into_hir_generics(ctx, item_id, span) - .hir_generics_or_empty() - .params; + let mut create_params = |result: &mut GenericsGenerationResult<'hir>| { + result.generics.into_hir_generics(ctx, span).hir_generics_or_empty().params + }; + + let parent = create_params(&mut self.parent); + let child = create_params(&mut self.child); // Order generics, firstly we have parent and child lifetimes, // then parent and child types and consts. @@ -209,7 +198,6 @@ impl<'hir> GenericsGenerationResults<'hir> { /// in `rustc_hir_analysis`, as we inherit all predicates from delegation signature. pub(super) fn all_predicates( &mut self, - item_id: NodeId, span: Span, ctx: &mut LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'hir>>, ) -> impl Iterator> { @@ -218,21 +206,14 @@ impl<'hir> GenericsGenerationResults<'hir> { // method call will be supported (if HIR generics were not obtained // then it means that we did not propagated them, thus we do not need // to generate predicates). - self.parent - .generics - .into_hir_generics(ctx, item_id, span) - .hir_generics_or_empty() - .predicates - .into_iter() - .chain( - self.child - .generics - .into_hir_generics(ctx, item_id, span) - .hir_generics_or_empty() - .predicates - .into_iter(), - ) - .copied() + let mut create_predicates = |result: &mut GenericsGenerationResult<'hir>| { + result.generics.into_hir_generics(ctx, span).hir_generics_or_empty().predicates + }; + + let parent = create_predicates(&mut self.parent); + let child = create_predicates(&mut self.child); + + parent.into_iter().chain(child).copied() } } @@ -242,7 +223,6 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { delegation: &Delegation, sig_id: DefId, item_id: NodeId, - span: Span, ) -> GenericsGenerationResults<'hir> { let delegation_parent_kind = self.tcx.def_kind(self.tcx.local_parent(self.local_def_id(item_id))); @@ -258,7 +238,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { // we will take those args that are in trait impl header trait ref. let parent = GenericsGenerationResult::new(DelegationGenerics::Default(None)); - let generics = self.get_external_generics(sig_id, false, span); + let generics = self.generic_params(sig_id).map(|i| i.collect()); let child = DelegationGenerics::TraitImpl(generics, child_user_specified); let child = GenericsGenerationResult::new(child); @@ -268,29 +248,28 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { let delegation_in_free_ctx = !matches!(delegation_parent_kind, DefKind::Trait | DefKind::Impl { .. }); - let root_function_in_trait = - matches!(self.tcx.def_kind(self.tcx.parent(sig_id)), DefKind::Trait); - - let generate_self = delegation_in_free_ctx && root_function_in_trait; - - let parent_generics_factory = |this: &mut Self, user_specified: bool| { - this.get_parent_generics(this.tcx.parent(sig_id), generate_self, user_specified, span) - }; + let sig_parent = self.tcx.parent(sig_id); + let sig_in_trait = matches!(self.tcx.def_kind(sig_parent), DefKind::Trait); let can_add_generics_to_parent = len >= 2 && self.get_resolution_id(segments[len - 2].id).is_some_and(|def_id| { matches!(self.tcx.def_kind(def_id), DefKind::Trait | DefKind::TraitAlias) }); + let generate_self = delegation_in_free_ctx && sig_in_trait; let parent_generics = if can_add_generics_to_parent { if segments[len - 2].args.is_some() { if generate_self { - DelegationGenerics::SelfAndUserSpecified(parent_generics_factory(self, true)) + // Take only first Self parameter, it is trait so Self must be present. + let params = self.generic_params(sig_parent).map(|i| i.take(1).collect()); + DelegationGenerics::SelfAndUserSpecified(params) } else { DelegationGenerics::UserSpecified } } else { - DelegationGenerics::Default(parent_generics_factory(self, false)) + let skip_self = !generate_self as usize; + let params = self.generic_params(sig_parent).map(|i| i.skip(skip_self).collect()); + DelegationGenerics::Default(params) } } else { DelegationGenerics::Default(None) @@ -299,7 +278,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { let child_generics = if child_user_specified { DelegationGenerics::UserSpecified } else { - DelegationGenerics::Default(self.get_external_generics(sig_id, false, span)) + DelegationGenerics::Default(self.generic_params(sig_id).map(|i| i.collect())) }; GenericsGenerationResults { @@ -310,57 +289,69 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { fn lower_delegation_generic_params( &mut self, - item_id: NodeId, span: Span, - params: &mut ThinVec, + params: &[ty::GenericParamDef], ) -> &'hir hir::Generics<'hir> { - for p in params.iter_mut() { - // We want to create completely new params, so we generate - // a new id, otherwise assertions will be triggered. - p.id = self.next_node_id(); - - // Remove default params, as they are not supported on functions - // and there will duplicate DefId when we try to lower them later. - match &mut p.kind { - GenericParamKind::Lifetime => {} - GenericParamKind::Type { default } => *default = None, - GenericParamKind::Const { default, .. } => *default = None, - } + let params = self.arena.alloc_from_iter(params.iter().map(|p| { + let def_kind = match p.kind { + GenericParamDefKind::Lifetime => DefKind::LifetimeParam, + GenericParamDefKind::Type { .. } => DefKind::TyParam, + GenericParamDefKind::Const { .. } => DefKind::ConstParam, + }; - // Note that we use self.disambiguator here, if we will create new every time - // we will get ICE if params have the same name. - self.resolver.insert_new_def_id( - p.id, - self.tcx - .create_def( - self.local_def_id(item_id), - Some(p.ident.name), - match p.kind { - GenericParamKind::Lifetime => DefKind::LifetimeParam, - GenericParamKind::Type { .. } => DefKind::TyParam, - GenericParamKind::Const { .. } => DefKind::ConstParam, - }, - None, - &mut self.disambiguator, - ) - .def_id(), - ); - } + let param_ident = Ident::new(p.name, span); + let def_name = Some(param_ident.name); + let path_data = def_kind.def_path_data(def_name); + let node_id = self.next_node_id(); + + let def_id = self.create_def(node_id, def_name, def_kind, path_data, span); - // Fallback to default generic param lowering, we modified them in the loop above. - let params = self.arena.alloc_from_iter( - params.iter().map(|p| self.lower_generic_param(p, hir::GenericParamSource::Generics)), - ); + let kind = match p.kind { + GenericParamDefKind::Lifetime => { + hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit } + } + GenericParamDefKind::Type { synthetic, .. } => { + hir::GenericParamKind::Type { default: None, synthetic } + } + GenericParamDefKind::Const { .. } => { + let hir_id = self.next_id(); + let kind = hir::TyKind::InferDelegation(hir::InferDelegation::DefId(p.def_id)); + + hir::GenericParamKind::Const { + ty: self.arena.alloc(hir::Ty { kind, hir_id, span }), + default: None, + } + } + }; + + // Important: we don't use `self.next_id()` as we want to execute + // `lower_node_id` routine so param's id is added to `self.children`. + let hir_id = self.lower_node_id(node_id); + + hir::GenericParam { + hir_id, + colon_span: Some(span), + def_id, + kind, + name: hir::ParamName::Plain(param_ident), + pure_wrt_drop: p.pure_wrt_drop, + source: hir::GenericParamSource::Generics, + span, + } + })); // HACK: for now we generate predicates such that all lifetimes are early bound, // we can not not generate early-bound lifetimes, but we can't know which of them // are late-bound at this level of compilation. // FIXME(fn_delegation): proper support for late bound lifetimes. + let predicates = + self.arena.alloc_from_iter(params.iter().filter_map(|p| { + p.is_lifetime().then(|| self.generate_lifetime_predicate(p, span)) + })); + self.arena.alloc(hir::Generics { params, - predicates: self.arena.alloc_from_iter(params.iter().filter_map(|p| { - p.is_lifetime().then(|| self.generate_lifetime_predicate(p, span)) - })), + predicates, has_where_clause_predicates: false, where_clause_span: span, span, @@ -376,11 +367,9 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { this.arena.alloc(hir::Lifetime { hir_id: this.next_id(), ident: p.name.ident(), - kind: rustc_hir::LifetimeKind::Param(p.def_id), - source: rustc_hir::LifetimeSource::Path { - angle_brackets: rustc_hir::AngleBrackets::Full, - }, - syntax: rustc_hir::LifetimeSyntax::ExplicitBound, + kind: hir::LifetimeKind::Param(p.def_id), + source: hir::LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full }, + syntax: hir::LifetimeSyntax::ExplicitBound, }) }; @@ -473,116 +462,8 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { }) } - fn get_external_generics( - &mut self, - id: DefId, - processing_parent: bool, - span: Span, - ) -> Option { - let generics = self.tcx.generics_of(id); - if generics.own_params.is_empty() { - return None; - } - - // Skip first Self parameter if we are in trait, it will be added later. - let to_skip = (processing_parent && generics.has_self) as usize; - - Some(Generics { - params: generics - .own_params - .iter() - .skip(to_skip) - .map(|p| GenericParam { - attrs: Default::default(), - bounds: Default::default(), - colon_span: None, - id: self.next_node_id(), - ident: Ident::new(p.name, span), - is_placeholder: false, - kind: match p.kind { - GenericParamDefKind::Lifetime => GenericParamKind::Lifetime, - GenericParamDefKind::Type { .. } => { - GenericParamKind::Type { default: None } - } - GenericParamDefKind::Const { .. } => self.map_const_kind(p, span), - }, - }) - .collect(), - where_clause: Default::default(), - span, - }) - } - - fn map_const_kind(&mut self, p: &ty::GenericParamDef, span: Span) -> GenericParamKind { - let const_type = self.tcx.type_of(p.def_id).instantiate_identity(); - - let (type_symbol, res) = match const_type.kind() { - ty::Bool => (sym::bool, Res::PrimTy(hir::PrimTy::Bool)), - ty::Uint(uint) => (uint.name(), Res::PrimTy(hir::PrimTy::Uint(*uint))), - ty::Int(int) => (int.name(), Res::PrimTy(hir::PrimTy::Int(*int))), - ty::Char => (sym::char, Res::PrimTy(hir::PrimTy::Char)), - _ => { - self.tcx - .dcx() - .span_delayed_bug(span, format!("Unexpected const type: {}", const_type)); - - (sym::dummy, Res::Err) - } - }; - - let node_id = self.next_node_id(); - - self.resolver.insert_partial_res(node_id, hir::def::PartialRes::new(res)); - - GenericParamKind::Const { - ty: Box::new(Ty { - id: node_id, - kind: TyKind::Path( - None, - Path { - segments: thin_vec![PathSegment { - ident: Ident::new(type_symbol, span), - id: self.next_node_id(), - args: None - }], - span, - tokens: None, - }, - ), - span, - tokens: None, - }), - span, - default: None, - } - } - - fn get_parent_generics( - &mut self, - id: DefId, - add_self: bool, - user_specified: bool, - span: Span, - ) -> Option { - // If args are user-specified we still maybe need to add self. - let mut generics = - if user_specified { None } else { self.get_external_generics(id, true, span) }; - - if add_self { - generics.get_or_insert_default().params.insert( - 0, - GenericParam { - id: self.next_node_id(), - ident: Ident::new(kw::SelfUpper, span), - attrs: Default::default(), - bounds: vec![], - is_placeholder: false, - kind: GenericParamKind::Type { default: None }, - colon_span: None, - }, - ); - } - - generics + fn generic_params(&mut self, id: DefId) -> Option> { + let params = &self.tcx.generics_of(id).own_params; + (!params.is_empty()).then(|| params.iter().cloned()) } } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index a2be51cfa31b4..2e421408aa566 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -678,7 +678,7 @@ pub fn lower_delayed_owner(tcx: TyCtxt<'_>, def_id: LocalDefId) { lowerer.lower_node(def_id); - for (&child_def_id, &owner) in &map { + for (child_def_id, owner) in map { tcx.feed_delayed_owner(child_def_id, owner); } } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 9526143fcace5..8cd119dfdd279 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3765,12 +3765,18 @@ pub struct DelegationGenerics { } #[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable_Generic)] -pub enum InferDelegationKind<'hir> { +pub enum InferDelegationSig<'hir> { Input(usize), // Place generics info here, as we always specify output type for delegations. Output(&'hir DelegationGenerics), } +#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable_Generic)] +pub enum InferDelegation<'hir> { + DefId(DefId), + Sig(DefId, InferDelegationSig<'hir>), +} + /// The various kinds of types recognized by the compiler. /// /// For an explanation of the `Unambig` generic parameter see the dev-guide: @@ -3780,7 +3786,7 @@ pub enum InferDelegationKind<'hir> { #[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum TyKind<'hir, Unambig = ()> { /// Actual type should be inherited from `DefId` signature - InferDelegation(DefId, InferDelegationKind<'hir>), + InferDelegation(InferDelegation<'hir>), /// A variable length slice (i.e., `[T]`). Slice(&'hir Ty<'hir>), /// A fixed length array (i.e., `[T; n]`). @@ -3931,7 +3937,7 @@ pub struct FnDecl<'hir> { impl<'hir> FnDecl<'hir> { pub fn opt_delegation_sig_id(&self) -> Option { if let FnRetTy::Return(ty) = self.output - && let TyKind::InferDelegation(sig_id, _) = ty.kind + && let TyKind::InferDelegation(InferDelegation::Sig(sig_id, _)) = ty.kind { return Some(sig_id); } @@ -3940,8 +3946,8 @@ impl<'hir> FnDecl<'hir> { pub fn opt_delegation_generics(&self) -> Option<&'hir DelegationGenerics> { if let FnRetTy::Return(ty) = self.output - && let TyKind::InferDelegation(_, kind) = ty.kind - && let InferDelegationKind::Output(generics) = kind + && let TyKind::InferDelegation(InferDelegation::Sig(_, kind)) = ty.kind + && let InferDelegationSig::Output(generics) = kind { return Some(generics); } diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 18244d62f2ae6..5bb4166bf6cb3 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -925,7 +925,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { hir::FnRetTy::Return(ty) => Some(ty), }; if let Some(ty) = output - && let hir::TyKind::InferDelegation(sig_id, _) = ty.kind + && let hir::TyKind::InferDelegation(hir::InferDelegation::Sig(sig_id, _)) = ty.kind { let bound_vars: Vec<_> = self.tcx.fn_sig(sig_id).skip_binder().bound_vars().iter().collect(); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 9396bf6352c59..1200f6e9e47ea 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2959,12 +2959,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } - fn lower_delegation_ty(&self, idx: hir::InferDelegationKind<'tcx>) -> Ty<'tcx> { - let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id()); + fn lower_delegation_ty(&self, infer: hir::InferDelegation<'tcx>) -> Ty<'tcx> { + match infer { + hir::InferDelegation::DefId(def_id) => { + self.tcx().type_of(def_id).instantiate_identity() + } + rustc_hir::InferDelegation::Sig(_, idx) => { + let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id()); - match idx { - hir::InferDelegationKind::Input(idx) => delegation_sig[idx], - hir::InferDelegationKind::Output { .. } => *delegation_sig.last().unwrap(), + match idx { + hir::InferDelegationSig::Input(idx) => delegation_sig[idx], + hir::InferDelegationSig::Output { .. } => *delegation_sig.last().unwrap(), + } + } } } @@ -2974,7 +2981,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let tcx = self.tcx(); let result_ty = match &hir_ty.kind { - hir::TyKind::InferDelegation(_, idx) => self.lower_delegation_ty(*idx), + hir::TyKind::InferDelegation(infer) => self.lower_delegation_ty(*infer), hir::TyKind::Slice(ty) => Ty::new_slice(tcx, self.lower_ty(ty)), hir::TyKind::Ptr(mt) => Ty::new_ptr(tcx, self.lower_ty(mt.ty), mt.mutbl), hir::TyKind::Ref(region, mt) => { diff --git a/tests/ui/delegation/generics/const-type-ice-153433.rs b/tests/ui/delegation/generics/const-type-ice-153433.rs new file mode 100644 index 0000000000000..edd6d0542a999 --- /dev/null +++ b/tests/ui/delegation/generics/const-type-ice-153433.rs @@ -0,0 +1,8 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +fn main() { + fn foo Foo>() {} + //~^ ERROR: cannot find trait `Foo` in this scope + reuse foo as bar; +} diff --git a/tests/ui/delegation/generics/const-type-ice-153433.stderr b/tests/ui/delegation/generics/const-type-ice-153433.stderr new file mode 100644 index 0000000000000..3b537e2f8988e --- /dev/null +++ b/tests/ui/delegation/generics/const-type-ice-153433.stderr @@ -0,0 +1,9 @@ +error[E0405]: cannot find trait `Foo` in this scope + --> $DIR/const-type-ice-153433.rs:5:33 + | +LL | fn foo Foo>() {} + | ^^^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0405`. diff --git a/tests/ui/delegation/generics/const-type-ice-153499.rs b/tests/ui/delegation/generics/const-type-ice-153499.rs new file mode 100644 index 0000000000000..debda0d04a18c --- /dev/null +++ b/tests/ui/delegation/generics/const-type-ice-153499.rs @@ -0,0 +1,13 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +trait Trait<'a, T, const F: fn(&CStr) -> usize> { + //~^ ERROR: cannot find type `CStr` in this scope + //~| ERROR: using function pointers as const generic parameters is forbidden + fn foo<'x: 'x, A, B>(&self) {} +} + +reuse Trait::foo; +//~^ ERROR: using function pointers as const generic parameters is forbidden + +fn main() {} diff --git a/tests/ui/delegation/generics/const-type-ice-153499.stderr b/tests/ui/delegation/generics/const-type-ice-153499.stderr new file mode 100644 index 0000000000000..02fd7197dcdc3 --- /dev/null +++ b/tests/ui/delegation/generics/const-type-ice-153499.stderr @@ -0,0 +1,30 @@ +error[E0425]: cannot find type `CStr` in this scope + --> $DIR/const-type-ice-153499.rs:4:33 + | +LL | trait Trait<'a, T, const F: fn(&CStr) -> usize> { + | ^^^^ not found in this scope + | +help: consider importing this struct + | +LL + use std::ffi::CStr; + | + +error: using function pointers as const generic parameters is forbidden + --> $DIR/const-type-ice-153499.rs:4:29 + | +LL | trait Trait<'a, T, const F: fn(&CStr) -> usize> { + | ^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool`, and `char` + +error: using function pointers as const generic parameters is forbidden + --> $DIR/const-type-ice-153499.rs:10:14 + | +LL | reuse Trait::foo; + | ^^^ + | + = note: the only supported types are integers, `bool`, and `char` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0425`.