diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 76f63d1d78a..b175333fee2 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1,6 +1,6 @@ use super::errors::{InvalidAbi, MisplacedRelaxTraitBound}; use super::ResolverAstLoweringExt; -use super::{AstOwner, ImplTraitContext, ImplTraitPosition}; +use super::{Arena, AstOwner, ImplTraitContext, ImplTraitPosition}; use super::{FnDeclKind, LoweringContext, ParamMode}; use rustc_ast::ptr::P; @@ -25,6 +25,7 @@ pub(super) struct ItemLowerer<'a, 'hir> { pub(super) tcx: TyCtxt<'hir>, pub(super) resolver: &'a mut ResolverAstLowering, + pub(super) ast_arena: &'a Arena<'static>, pub(super) ast_index: &'a IndexVec>, pub(super) owners: &'a mut IndexVec>>, } @@ -60,6 +61,7 @@ fn with_lctx( tcx: self.tcx, resolver: self.resolver, arena: self.tcx.hir_arena, + ast_arena: self.ast_arena, // HirId handling. bodies: Vec::new(), diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 3a94c7a91b2..cec91757e98 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -44,6 +44,7 @@ use crate::errors::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait}; +use rustc_arena::declare_arena; use rustc_ast::ptr::P; use rustc_ast::visit; use rustc_ast::{self as ast, *}; @@ -95,6 +96,13 @@ struct LoweringContext<'a, 'hir> { /// Used to allocate HIR nodes. arena: &'hir hir::Arena<'hir>, + /// Used to allocate temporary AST nodes for use during lowering. + /// This allows us to create "fake" AST -- these nodes can sometimes + /// be allocated on the stack, but other times we need them to live longer + /// than the current stack frame, so they can be collected into vectors + /// and things like that. + ast_arena: &'a Arena<'static>, + /// Bodies inside the owner being lowered. bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>, /// Attributes inside the owner being lowered. @@ -140,6 +148,15 @@ struct LoweringContext<'a, 'hir> { generics_def_id_map: Vec>, } +declare_arena!([ + [] tys: rustc_ast::Ty, + [] aba: rustc_ast::AngleBracketedArgs, + [] ptr: rustc_ast::PolyTraitRef, + // This _marker field is needed because `declare_arena` creates `Arena<'tcx>` and we need to + // use `'tcx`. If we don't have this we get a compile error. + [] _marker: std::marker::PhantomData<&'tcx ()>, +]); + trait ResolverAstLoweringExt { fn legacy_const_generic_args(&self, expr: &Expr) -> Option>; fn get_partial_res(&self, id: NodeId) -> Option; @@ -401,10 +418,13 @@ pub fn lower_to_hir<'hir>(tcx: TyCtxt<'hir>, (): ()) -> hir::Crate<'hir> { tcx.definitions_untracked().def_index_count(), ); + let ast_arena = Arena::default(); + for def_id in ast_index.indices() { item::ItemLowerer { tcx, resolver: &mut resolver, + ast_arena: &ast_arena, ast_index: &ast_index, owners: &mut owners, } @@ -964,12 +984,8 @@ fn lower_assoc_ty_constraint( } GenericArgs::Parenthesized(ref data) => { self.emit_bad_parenthesized_trait_in_assoc_ty(data); - self.lower_angle_bracketed_parameter_data( - &data.as_angle_bracketed_args(), - ParamMode::Explicit, - itctx, - ) - .0 + let aba = self.ast_arena.aba.alloc(data.as_angle_bracketed_args()); + self.lower_angle_bracketed_parameter_data(aba, ParamMode::Explicit, itctx).0 } }; gen_args_ctor.into_generic_args(self) @@ -1037,15 +1053,13 @@ fn lower_assoc_ty_constraint( self.with_dyn_type_scope(false, |this| { let node_id = this.next_node_id(); - let ty = this.lower_ty( - &Ty { - id: node_id, - kind: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()), - span: this.lower_span(constraint.span), - tokens: None, - }, - itctx, - ); + let ty = this.ast_arena.tys.alloc(Ty { + id: node_id, + kind: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()), + span: this.lower_span(constraint.span), + tokens: None, + }); + let ty = this.lower_ty(ty, itctx); hir::TypeBindingKind::Equality { term: ty.into() } }) @@ -1181,12 +1195,13 @@ fn lower_path_ty( && let Res::Def(DefKind::Trait | DefKind::TraitAlias, _) = partial_res.base_res() { let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| { + let poly_trait_ref = this.ast_arena.ptr.alloc(PolyTraitRef { + bound_generic_params: vec![], + trait_ref: TraitRef { path: path.clone(), ref_id: t.id }, + span: t.span + }); let bound = this.lower_poly_trait_ref( - &PolyTraitRef { - bound_generic_params: vec![], - trait_ref: TraitRef { path: path.clone(), ref_id: t.id }, - span: t.span - }, + poly_trait_ref, itctx, ); let bounds = this.arena.alloc_from_iter([bound]);