diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 12d1b8404eb..85d3bf66d8e 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -83,6 +83,8 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { task_context: None, current_item: None, captured_lifetimes: None, + impl_trait_defs: Vec::new(), + impl_trait_bounds: Vec::new(), allow_try_trait: Some([sym::try_trait_v2, sym::yeet_desugar_details][..].into()), allow_gen_future: Some([sym::gen_future][..].into()), allow_into_future: Some([sym::into_future][..].into()), @@ -264,16 +266,11 @@ impl<'hir> LoweringContext<'_, 'hir> { let body_id = this.lower_maybe_async_body(span, &decl, asyncness, body.as_deref()); - let (generics, decl) = - this.add_implicit_generics(generics, id, |this, idty, idpb| { - let ret_id = asyncness.opt_return_id(); - this.lower_fn_decl( - &decl, - Some((id, idty, idpb)), - FnDeclKind::Fn, - ret_id, - ) - }); + let itctx = ImplTraitContext::Universal(this.current_hir_id_owner); + let (generics, decl) = this.lower_generics(generics, id, itctx, |this| { + let ret_id = asyncness.opt_return_id(); + this.lower_fn_decl(&decl, Some(id), FnDeclKind::Fn, ret_id) + }); let sig = hir::FnSig { decl, header: this.lower_fn_header(header), @@ -311,57 +308,59 @@ impl<'hir> LoweringContext<'_, 'hir> { // // type Foo = Foo1 // opaque type Foo1: Trait - let ty = self.lower_ty(ty, ImplTraitContext::TypeAliasesOpaqueTy); let mut generics = generics.clone(); add_ty_alias_where_clause(&mut generics, where_clauses, true); - let generics = self.lower_generics( + let (generics, ty) = self.lower_generics( &generics, + id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), + |this| this.lower_ty(ty, ImplTraitContext::TypeAliasesOpaqueTy), ); hir::ItemKind::TyAlias(ty, generics) } ItemKind::TyAlias(box TyAlias { ref generics, ref where_clauses, ty: None, .. }) => { - let ty = self.arena.alloc(self.ty(span, hir::TyKind::Err)); let mut generics = generics.clone(); add_ty_alias_where_clause(&mut generics, *where_clauses, true); - let generics = self.lower_generics( + let (generics, ty) = self.lower_generics( &generics, + id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), + |this| this.arena.alloc(this.ty(span, hir::TyKind::Err)), ); hir::ItemKind::TyAlias(ty, generics) } - ItemKind::Enum(ref enum_definition, ref generics) => hir::ItemKind::Enum( - hir::EnumDef { - variants: self.arena.alloc_from_iter( - enum_definition.variants.iter().map(|x| self.lower_variant(x)), - ), - }, - self.lower_generics( + ItemKind::Enum(ref enum_definition, ref generics) => { + let (generics, variants) = self.lower_generics( generics, + id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), - ), - ), + |this| { + this.arena.alloc_from_iter( + enum_definition.variants.iter().map(|x| this.lower_variant(x)), + ) + }, + ); + hir::ItemKind::Enum(hir::EnumDef { variants }, generics) + } ItemKind::Struct(ref struct_def, ref generics) => { - let struct_def = self.lower_variant_data(hir_id, struct_def); - hir::ItemKind::Struct( - struct_def, - self.lower_generics( - generics, - ImplTraitContext::Disallowed(ImplTraitPosition::Generic), - ), - ) + let (generics, struct_def) = self.lower_generics( + generics, + id, + ImplTraitContext::Disallowed(ImplTraitPosition::Generic), + |this| this.lower_variant_data(hir_id, struct_def), + ); + hir::ItemKind::Struct(struct_def, generics) } ItemKind::Union(ref vdata, ref generics) => { - let vdata = self.lower_variant_data(hir_id, vdata); - hir::ItemKind::Union( - vdata, - self.lower_generics( - generics, - ImplTraitContext::Disallowed(ImplTraitPosition::Generic), - ), - ) + let (generics, vdata) = self.lower_generics( + generics, + id, + ImplTraitContext::Disallowed(ImplTraitPosition::Generic), + |this| this.lower_variant_data(hir_id, vdata), + ); + hir::ItemKind::Union(vdata, generics) } ItemKind::Impl(box Impl { unsafety, @@ -386,8 +385,9 @@ impl<'hir> LoweringContext<'_, 'hir> { // method, it will not be considered an in-band // lifetime to be added, but rather a reference to a // parent lifetime. + let itctx = ImplTraitContext::Universal(self.current_hir_id_owner); let (generics, (trait_ref, lowered_ty)) = - self.add_implicit_generics(ast_generics, id, |this, _, _| { + self.lower_generics(ast_generics, id, itctx, |this| { let trait_ref = trait_ref.as_ref().map(|trait_ref| { this.lower_trait_ref( trait_ref, @@ -432,34 +432,38 @@ impl<'hir> LoweringContext<'_, 'hir> { ref bounds, ref items, }) => { - let bounds = self.lower_param_bounds( - bounds, - ImplTraitContext::Disallowed(ImplTraitPosition::Bound), - ); - let items = self - .arena - .alloc_from_iter(items.iter().map(|item| self.lower_trait_item_ref(item))); - hir::ItemKind::Trait( - is_auto, - self.lower_unsafety(unsafety), - self.lower_generics( - generics, - ImplTraitContext::Disallowed(ImplTraitPosition::Generic), - ), - bounds, - items, - ) - } - ItemKind::TraitAlias(ref generics, ref bounds) => hir::ItemKind::TraitAlias( - self.lower_generics( + let (generics, (unsafety, items, bounds)) = self.lower_generics( generics, + id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), - ), - self.lower_param_bounds( - bounds, - ImplTraitContext::Disallowed(ImplTraitPosition::Bound), - ), - ), + |this| { + let bounds = this.lower_param_bounds( + bounds, + ImplTraitContext::Disallowed(ImplTraitPosition::Bound), + ); + let items = this.arena.alloc_from_iter( + items.iter().map(|item| this.lower_trait_item_ref(item)), + ); + let unsafety = this.lower_unsafety(unsafety); + (unsafety, items, bounds) + }, + ); + hir::ItemKind::Trait(is_auto, unsafety, generics, bounds, items) + } + ItemKind::TraitAlias(ref generics, ref bounds) => { + let (generics, bounds) = self.lower_generics( + generics, + id, + ImplTraitContext::Disallowed(ImplTraitPosition::Generic), + |this| { + this.lower_param_bounds( + bounds, + ImplTraitContext::Disallowed(ImplTraitPosition::Bound), + ) + }, + ); + hir::ItemKind::TraitAlias(generics, bounds) + } ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => { let body = P(self.lower_mac_args(body)); let macro_kind = self.resolver.decl_macro_kind(self.resolver.local_def_id(id)); @@ -651,8 +655,9 @@ impl<'hir> LoweringContext<'_, 'hir> { kind: match i.kind { ForeignItemKind::Fn(box Fn { ref sig, ref generics, .. }) => { let fdec = &sig.decl; + let itctx = ImplTraitContext::Universal(self.current_hir_id_owner); let (generics, (fn_dec, fn_args)) = - self.add_implicit_generics(generics, i.id, |this, _, _| { + self.lower_generics(generics, i.id, itctx, |this| { ( // Disallow `impl Trait` in foreign items. this.lower_fn_decl(fdec, None, FnDeclKind::ExternFn, None), @@ -789,24 +794,25 @@ impl<'hir> LoweringContext<'_, 'hir> { ref ty, .. }) => { - let ty = ty.as_ref().map(|x| { - self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type)) - }); let mut generics = generics.clone(); add_ty_alias_where_clause(&mut generics, where_clauses, false); - let generics = self.lower_generics( + self.lower_generics( &generics, + i.id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), - ); - let kind = hir::TraitItemKind::Type( - self.lower_param_bounds( - bounds, - ImplTraitContext::Disallowed(ImplTraitPosition::Generic), - ), - ty, - ); - - (generics, kind) + |this| { + let ty = ty.as_ref().map(|x| { + this.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type)) + }); + hir::TraitItemKind::Type( + this.lower_param_bounds( + bounds, + ImplTraitContext::Disallowed(ImplTraitPosition::Generic), + ), + ty, + ) + }, + ) } AssocItemKind::MacCall(..) => panic!("macro item shouldn't exist at this point"), }; @@ -876,21 +882,21 @@ impl<'hir> LoweringContext<'_, 'hir> { AssocItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => { let mut generics = generics.clone(); add_ty_alias_where_clause(&mut generics, *where_clauses, false); - let generics = self.lower_generics( + self.lower_generics( &generics, + i.id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), - ); - let kind = match ty { - None => { - let ty = self.arena.alloc(self.ty(i.span, hir::TyKind::Err)); - hir::ImplItemKind::TyAlias(ty) - } - Some(ty) => { - let ty = self.lower_ty(ty, ImplTraitContext::TypeAliasesOpaqueTy); - hir::ImplItemKind::TyAlias(ty) - } - }; - (generics, kind) + |this| match ty { + None => { + let ty = this.arena.alloc(this.ty(i.span, hir::TyKind::Err)); + hir::ImplItemKind::TyAlias(ty) + } + Some(ty) => { + let ty = this.lower_ty(ty, ImplTraitContext::TypeAliasesOpaqueTy); + hir::ImplItemKind::TyAlias(ty) + } + }, + ) } AssocItemKind::MacCall(..) => panic!("`TyMac` should have been expanded by now"), }; @@ -1231,8 +1237,9 @@ impl<'hir> LoweringContext<'_, 'hir> { is_async: Option, ) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) { let header = self.lower_fn_header(sig.header); - let (generics, decl) = self.add_implicit_generics(generics, id, |this, idty, idpb| { - this.lower_fn_decl(&sig.decl, Some((id, idty, idpb)), kind, is_async) + let itctx = ImplTraitContext::Universal(self.current_hir_id_owner); + let (generics, decl) = self.lower_generics(generics, id, itctx, |this| { + this.lower_fn_decl(&sig.decl, Some(id), kind, is_async) }); (generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) }) } @@ -1289,11 +1296,18 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - pub(super) fn lower_generics_mut( + /// Return the pair of the lowered `generics` as `hir::Generics` and the evaluation of `f` with + /// the carried impl trait definitions and bounds. + fn lower_generics( &mut self, generics: &Generics, - mut itctx: ImplTraitContext<'_, 'hir>, - ) -> GenericsCtor<'hir> { + parent_node_id: NodeId, + itctx: ImplTraitContext, + f: impl FnOnce(&mut Self) -> T, + ) -> (&'hir hir::Generics<'hir>, T) { + debug_assert!(self.impl_trait_defs.is_empty()); + debug_assert!(self.impl_trait_bounds.is_empty()); + // Error if `?Trait` bounds in where clauses don't refer directly to type parameters. // Note: we used to clone these bounds directly onto the type parameter (and avoid lowering // these into hir when we lower thee where clauses), but this makes it quite difficult to @@ -1341,9 +1355,9 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - let mut predicates = SmallVec::new(); + let mut predicates: SmallVec<[hir::WherePredicate<'hir>; 4]> = SmallVec::new(); predicates.extend(generics.params.iter().filter_map(|param| { - let bounds = self.lower_param_bounds(¶m.bounds, itctx.reborrow()); + let bounds = self.lower_param_bounds(¶m.bounds, itctx); self.lower_generic_bound_predicate( param.ident, param.id, @@ -1360,22 +1374,31 @@ impl<'hir> LoweringContext<'_, 'hir> { .map(|predicate| self.lower_where_predicate(predicate)), ); - GenericsCtor { - params: self.lower_generic_params_mut(&generics.params).collect(), - predicates, - has_where_clause: !generics.where_clause.predicates.is_empty(), - where_clause_span: self.lower_span(generics.where_clause.span), - span: self.lower_span(generics.span), - } - } + let mut params: Vec<_> = self.lower_generic_params_mut(&generics.params).collect(); + let has_where_clause = !generics.where_clause.predicates.is_empty(); + let where_clause_span = self.lower_span(generics.where_clause.span); + let span = self.lower_span(generics.span); + let res = f(self); - pub(super) fn lower_generics( - &mut self, - generics: &Generics, - itctx: ImplTraitContext<'_, 'hir>, - ) -> &'hir hir::Generics<'hir> { - let generics_ctor = self.lower_generics_mut(generics, itctx); - generics_ctor.into_generics(self.arena) + let extra_lifetimes = self.resolver.take_extra_lifetime_params(parent_node_id); + let impl_trait_defs = std::mem::take(&mut self.impl_trait_defs); + params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| { + self.lifetime_res_to_generic_param(ident, node_id, res) + })); + params.extend(impl_trait_defs.into_iter()); + + let impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds); + predicates.extend(impl_trait_bounds.into_iter()); + + let lowered_generics = self.arena.alloc(hir::Generics { + params: self.arena.alloc_from_iter(params), + predicates: self.arena.alloc_from_iter(predicates), + has_where_clause, + where_clause_span, + span, + }); + + (lowered_generics, res) } pub(super) fn lower_generic_bound_predicate( @@ -1491,24 +1514,3 @@ impl<'hir> LoweringContext<'_, 'hir> { } } } - -/// Helper struct for delayed construction of Generics. -pub(super) struct GenericsCtor<'hir> { - pub(super) params: SmallVec<[hir::GenericParam<'hir>; 4]>, - pub(super) predicates: SmallVec<[hir::WherePredicate<'hir>; 4]>, - has_where_clause: bool, - where_clause_span: Span, - span: Span, -} - -impl<'hir> GenericsCtor<'hir> { - pub(super) fn into_generics(self, arena: &'hir Arena<'hir>) -> &'hir hir::Generics<'hir> { - arena.alloc(hir::Generics { - params: arena.alloc_from_iter(self.params), - predicates: arena.alloc_from_iter(self.predicates), - has_where_clause: self.has_where_clause, - where_clause_span: self.where_clause_span, - span: self.span, - }) - } -} diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index e59bc9aa6b3..2e93ce2f47e 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -121,6 +121,9 @@ struct LoweringContext<'a, 'hir: 'a> { local_id_to_def_id: SortedMap, trait_map: FxHashMap>, + impl_trait_defs: Vec>, + impl_trait_bounds: Vec>, + /// NodeIds that are lowered inside the current HIR owner. node_id_to_local_id: FxHashMap, @@ -243,14 +246,14 @@ pub trait ResolverAstLowering { /// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree, /// and if so, what meaning it has. -#[derive(Debug)] -enum ImplTraitContext<'b, 'a> { +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +enum ImplTraitContext { /// Treat `impl Trait` as shorthand for a new universal generic parameter. /// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually /// equivalent to a fresh universal parameter like `fn foo(x: T)`. /// /// Newly generated parameters should be inserted into the given `Vec`. - Universal(&'b mut Vec>, &'b mut Vec>, LocalDefId), + Universal(LocalDefId), /// Treat `impl Trait` as shorthand for a new opaque type. /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually @@ -290,18 +293,6 @@ enum ImplTraitPosition { ImplReturn, } -impl<'a> ImplTraitContext<'_, 'a> { - fn reborrow<'this>(&'this mut self) -> ImplTraitContext<'this, 'a> { - use self::ImplTraitContext::*; - match self { - Universal(params, bounds, parent) => Universal(params, bounds, *parent), - ReturnPositionOpaqueTy { origin } => ReturnPositionOpaqueTy { origin: *origin }, - TypeAliasesOpaqueTy => TypeAliasesOpaqueTy, - Disallowed(pos) => Disallowed(*pos), - } - } -} - impl std::fmt::Display for ImplTraitPosition { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let name = match self { @@ -479,6 +470,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let current_owner = std::mem::replace(&mut self.current_hir_id_owner, def_id); let current_local_counter = std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1)); + let current_impl_trait_defs = std::mem::take(&mut self.impl_trait_defs); + let current_impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds); // Always allocate the first `HirId` for the owner itself. let _old = self.node_id_to_local_id.insert(owner, hir::ItemLocalId::new(0)); @@ -486,6 +479,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let item = f(self); debug_assert_eq!(def_id, item.def_id()); + // `f` should have consumed all the elements in these vectors when constructing `item`. + debug_assert!(self.impl_trait_defs.is_empty()); + debug_assert!(self.impl_trait_bounds.is_empty()); let info = self.make_owner_info(item); self.attrs = current_attrs; @@ -495,6 +491,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.trait_map = current_trait_map; self.current_hir_id_owner = current_owner; self.item_local_id_counter = current_local_counter; + self.impl_trait_defs = current_impl_trait_defs; + self.impl_trait_bounds = current_impl_trait_bounds; let _old = self.children.insert(def_id, hir::MaybeOwner::Owner(info)); debug_assert!(_old.is_none()) @@ -694,46 +692,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }) } - /// Creates a new `hir::GenericParam` for every new `Fresh` lifetime and - /// universal `impl Trait` type parameter encountered while evaluating `f`. - /// Definitions are created with the provided `parent_def_id`. - fn add_implicit_generics( - &mut self, - generics: &Generics, - parent_node_id: NodeId, - f: impl FnOnce( - &mut Self, - &mut Vec>, - &mut Vec>, - ) -> T, - ) -> (&'hir hir::Generics<'hir>, T) { - let mut impl_trait_defs = Vec::new(); - let mut impl_trait_bounds = Vec::new(); - let mut lowered_generics = self.lower_generics_mut( - generics, - ImplTraitContext::Universal( - &mut impl_trait_defs, - &mut impl_trait_bounds, - self.current_hir_id_owner, - ), - ); - let res = f(self, &mut impl_trait_defs, &mut impl_trait_bounds); - - let extra_lifetimes = self.resolver.take_extra_lifetime_params(parent_node_id); - lowered_generics.params.extend( - extra_lifetimes - .into_iter() - .filter_map(|(ident, node_id, res)| { - self.lifetime_res_to_generic_param(ident, node_id, res) - }) - .chain(impl_trait_defs), - ); - lowered_generics.predicates.extend(impl_trait_bounds); - - let lowered_generics = lowered_generics.into_generics(self.arena); - (lowered_generics, res) - } - /// Setup lifetime capture for and impl-trait. /// The captures will be added to `captures`. fn while_capturing_lifetimes( @@ -898,7 +856,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_assoc_ty_constraint( &mut self, constraint: &AssocConstraint, - mut itctx: ImplTraitContext<'_, 'hir>, + itctx: ImplTraitContext, ) -> hir::TypeBinding<'hir> { debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx); @@ -906,12 +864,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let gen_args = if let Some(ref gen_args) = constraint.gen_args { let gen_args_ctor = match gen_args { GenericArgs::AngleBracketed(ref data) => { - self.lower_angle_bracketed_parameter_data( - data, - ParamMode::Explicit, - itctx.reborrow(), - ) - .0 + self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0 } GenericArgs::Parenthesized(ref data) => { let mut err = self.sess.struct_span_err( @@ -923,7 +876,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.lower_angle_bracketed_parameter_data( &data.as_angle_bracketed_args(), ParamMode::Explicit, - itctx.reborrow(), + itctx, ) .0 } @@ -962,7 +915,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // so desugar to // // fn foo(x: dyn Iterator) - ImplTraitContext::Universal(_, _, parent) if self.is_in_dyn_type => { + ImplTraitContext::Universal(parent) if self.is_in_dyn_type => { parent_def_id = parent; (true, itctx) } @@ -1036,7 +989,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_generic_arg( &mut self, arg: &ast::GenericArg, - itctx: ImplTraitContext<'_, 'hir>, + itctx: ImplTraitContext, ) -> hir::GenericArg<'hir> { match arg { ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(<)), @@ -1103,7 +1056,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext<'_, 'hir>) -> &'hir hir::Ty<'hir> { + fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> { self.arena.alloc(self.lower_ty_direct(t, itctx)) } @@ -1113,7 +1066,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { qself: &Option, path: &Path, param_mode: ParamMode, - itctx: ImplTraitContext<'_, 'hir>, + itctx: ImplTraitContext, ) -> hir::Ty<'hir> { let id = self.lower_node_id(t.id); let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx); @@ -1128,7 +1081,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.ty(span, hir::TyKind::Tup(tys)) } - fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_, 'hir>) -> hir::Ty<'hir> { + fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> { let kind = match t.kind { TyKind::Infer => hir::TyKind::Infer, TyKind::Err => hir::TyKind::Err, @@ -1160,11 +1113,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { })) }), TyKind::Never => hir::TyKind::Never, - TyKind::Tup(ref tys) => { - hir::TyKind::Tup(self.arena.alloc_from_iter( - tys.iter().map(|ty| self.lower_ty_direct(ty, itctx.reborrow())), - )) - } + TyKind::Tup(ref tys) => hir::TyKind::Tup( + self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))), + ), TyKind::Paren(ref ty) => { return self.lower_ty_direct(ty, itctx); } @@ -1198,7 +1149,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { GenericBound::Trait( ref ty, TraitBoundModifier::None | TraitBoundModifier::MaybeConst, - ) => Some(this.lower_poly_trait_ref(ty, itctx.reborrow())), + ) => Some(this.lower_poly_trait_ref(ty, itctx)), // `~const ?Bound` will cause an error during AST validation // anyways, so treat it like `?Bound` as compilation proceeds. GenericBound::Trait( @@ -1235,32 +1186,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { |this| this.lower_param_bounds(bounds, nested_itctx), ) } - ImplTraitContext::Universal( - in_band_ty_params, - in_band_ty_bounds, - parent_def_id, - ) => { + ImplTraitContext::Universal(parent_def_id) => { // Add a definition for the in-band `Param`. let def_id = self.resolver.local_def_id(def_node_id); - let hir_bounds = self.lower_param_bounds( - bounds, - ImplTraitContext::Universal( - in_band_ty_params, - in_band_ty_bounds, - parent_def_id, - ), - ); + let hir_bounds = self + .lower_param_bounds(bounds, ImplTraitContext::Universal(parent_def_id)); // Set the name to `impl Bound1 + Bound2`. let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span); - in_band_ty_params.push(hir::GenericParam { + let param = hir::GenericParam { hir_id: self.lower_node_id(def_node_id), name: ParamName::Plain(self.lower_ident(ident)), pure_wrt_drop: false, span: self.lower_span(span), kind: hir::GenericParamKind::Type { default: None, synthetic: true }, colon_span: None, - }); + }; + self.impl_trait_defs.push(param); + if let Some(preds) = self.lower_generic_bound_predicate( ident, def_node_id, @@ -1268,7 +1211,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir_bounds, hir::PredicateOrigin::ImplTrait, ) { - in_band_ty_bounds.push(preds) + self.impl_trait_bounds.push(preds) } hir::TyKind::Path(hir::QPath::Resolved( @@ -1439,26 +1382,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // `make_ret_async`: if `Some`, converts `-> T` into `-> impl Future` in the // return type. This is used for `async fn` declarations. The `NodeId` is the ID of the // return type `impl Trait` item. + #[tracing::instrument(level = "debug", skip(self))] fn lower_fn_decl( &mut self, decl: &FnDecl, - mut in_band_ty_params: Option<( - NodeId, - &mut Vec>, - &mut Vec>, - )>, + fn_node_id: Option, kind: FnDeclKind, make_ret_async: Option, ) -> &'hir hir::FnDecl<'hir> { - debug!( - "lower_fn_decl(\ - fn_decl: {:?}, \ - in_band_ty_params: {:?}, \ - kind: {:?}, \ - make_ret_async: {:?})", - decl, in_band_ty_params, kind, make_ret_async, - ); - let c_variadic = decl.c_variadic(); // Skip the `...` (`CVarArgs`) trailing arguments from the AST, @@ -1469,10 +1400,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { inputs = &inputs[..inputs.len() - 1]; } let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| { - if let Some((_, ibty, ibpb)) = &mut in_band_ty_params { + if fn_node_id.is_some() { self.lower_ty_direct( ¶m.ty, - ImplTraitContext::Universal(ibty, ibpb, self.current_hir_id_owner), + ImplTraitContext::Universal(self.current_hir_id_owner), ) } else { self.lower_ty_direct( @@ -1494,15 +1425,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let output = if let Some(ret_id) = make_ret_async { self.lower_async_fn_ret_ty( &decl.output, - in_band_ty_params.expect("`make_ret_async` but no `fn_def_id`").0, + fn_node_id.expect("`make_ret_async` but no `fn_def_id`"), ret_id, ) } else { match decl.output { FnRetTy::Ty(ref ty) => { - let context = match in_band_ty_params { - Some((node_id, _, _)) if kind.impl_trait_return_allowed() => { - let fn_def_id = self.resolver.local_def_id(node_id); + let context = match fn_node_id { + Some(fn_node_id) if kind.impl_trait_return_allowed() => { + let fn_def_id = self.resolver.local_def_id(fn_node_id); ImplTraitContext::ReturnPositionOpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id), } @@ -1788,7 +1719,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_param_bound( &mut self, tpb: &GenericBound, - itctx: ImplTraitContext<'_, 'hir>, + itctx: ImplTraitContext, ) -> hir::GenericBound<'hir> { match tpb { GenericBound::Trait(p, modifier) => hir::GenericBound::Trait( @@ -1966,11 +1897,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn lower_trait_ref( - &mut self, - p: &TraitRef, - itctx: ImplTraitContext<'_, 'hir>, - ) -> hir::TraitRef<'hir> { + fn lower_trait_ref(&mut self, p: &TraitRef, itctx: ImplTraitContext) -> hir::TraitRef<'hir> { let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) { hir::QPath::Resolved(None, path) => path, qpath => panic!("lower_trait_ref: unexpected QPath `{:?}`", qpath), @@ -1982,25 +1909,25 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_poly_trait_ref( &mut self, p: &PolyTraitRef, - mut itctx: ImplTraitContext<'_, 'hir>, + itctx: ImplTraitContext, ) -> hir::PolyTraitRef<'hir> { let bound_generic_params = self.lower_generic_params(&p.bound_generic_params); let trait_ref = self.with_lifetime_binder(p.trait_ref.ref_id, |this| { - this.lower_trait_ref(&p.trait_ref, itctx.reborrow()) + this.lower_trait_ref(&p.trait_ref, itctx) }); hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) } } - fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext<'_, 'hir>) -> hir::MutTy<'hir> { + fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> { hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl } } fn lower_param_bounds( &mut self, bounds: &[GenericBound], - itctx: ImplTraitContext<'_, 'hir>, + itctx: ImplTraitContext, ) -> hir::GenericBounds<'hir> { self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx)) } @@ -2008,9 +1935,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_param_bounds_mut<'s>( &'s mut self, bounds: &'s [GenericBound], - mut itctx: ImplTraitContext<'s, 'hir>, + itctx: ImplTraitContext, ) -> impl Iterator> + Captures<'s> + Captures<'a> { - bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx.reborrow())) + bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx)) } /// Lowers a block directly to an expression, presuming that it diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 7fc8aac5116..d56974b773d 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -21,11 +21,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { qself: &Option, p: &Path, param_mode: ParamMode, - mut itctx: ImplTraitContext<'_, 'hir>, + itctx: ImplTraitContext, ) -> hir::QPath<'hir> { debug!("lower_qpath(id: {:?}, qself: {:?}, p: {:?})", id, qself, p); let qself_position = qself.as_ref().map(|q| q.position); - let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx.reborrow())); + let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx)); let partial_res = self.resolver.get_partial_res(id).unwrap_or_else(|| PartialRes::new(Res::Err)); @@ -70,7 +70,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { segment, param_mode, parenthesized_generic_args, - itctx.reborrow(), + itctx, ) }, )), @@ -116,7 +116,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { segment, param_mode, ParenthesizedGenericArgs::Err, - itctx.reborrow(), + itctx, )); let qpath = hir::QPath::TypeRelative(ty, hir_segment); @@ -180,7 +180,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { segment: &PathSegment, param_mode: ParamMode, parenthesized_generic_args: ParenthesizedGenericArgs, - itctx: ImplTraitContext<'_, 'hir>, + itctx: ImplTraitContext, ) -> hir::PathSegment<'hir> { debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment,); let (mut generic_args, infer_args) = if let Some(ref generic_args) = segment.args { @@ -318,7 +318,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &mut self, data: &AngleBracketedArgs, param_mode: ParamMode, - mut itctx: ImplTraitContext<'_, 'hir>, + itctx: ImplTraitContext, ) -> (GenericArgsCtor<'hir>, bool) { let has_non_lt_args = data.args.iter().any(|arg| match arg { AngleBracketedArg::Arg(ast::GenericArg::Lifetime(_)) @@ -329,14 +329,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .args .iter() .filter_map(|arg| match arg { - AngleBracketedArg::Arg(arg) => Some(self.lower_generic_arg(arg, itctx.reborrow())), + AngleBracketedArg::Arg(arg) => Some(self.lower_generic_arg(arg, itctx)), AngleBracketedArg::Constraint(_) => None, }) .collect(); let bindings = self.arena.alloc_from_iter(data.args.iter().filter_map(|arg| match arg { - AngleBracketedArg::Constraint(c) => { - Some(self.lower_assoc_ty_constraint(c, itctx.reborrow())) - } + AngleBracketedArg::Constraint(c) => Some(self.lower_assoc_ty_constraint(c, itctx)), AngleBracketedArg::Arg(_) => None, })); let ctor = GenericArgsCtor { args, bindings, parenthesized: false, span: data.span };