diff --git a/Cargo.lock b/Cargo.lock index 8ac10d7d4fb53..33a24c3b535d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3526,7 +3526,6 @@ version = "0.0.0" dependencies = [ "rustc_abi", "rustc_ast", - "rustc_ast_pretty", "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 4eff1352d7e66..c95c16ef0809d 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -4308,6 +4308,17 @@ impl TryFrom for ForeignItemKind { pub type ForeignItem = Item; +#[derive(Debug)] +pub enum AstOwner { + NonOwner, + Synthetic(rustc_span::def_id::LocalDefId), + Crate(Box), + Item(Box), + TraitItem(Box), + ImplItem(Box), + ForeignItem(Box), +} + // Some nodes are used a lot. Make sure they don't unintentionally get bigger. #[cfg(target_pointer_width = "64")] mod size_asserts { diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 881b6ff107b56..0b81ad5ff952e 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -361,7 +361,10 @@ pub fn walk_flat_map_stmt( stmts } -fn walk_flat_map_stmt_kind(vis: &mut T, kind: StmtKind) -> SmallVec<[StmtKind; 1]> { +pub fn walk_flat_map_stmt_kind( + vis: &mut T, + kind: StmtKind, +) -> SmallVec<[StmtKind; 1]> { match kind { StmtKind::Let(mut local) => smallvec![StmtKind::Let({ vis.visit_local(&mut local); diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml index 42befe958633b..f9c08de02512f 100644 --- a/compiler/rustc_ast_lowering/Cargo.toml +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -10,7 +10,6 @@ doctest = false # tidy-alphabetical-start rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } -rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs index c70e7d3872d79..b52af8fd3715a 100644 --- a/compiler/rustc_ast_lowering/src/block.rs +++ b/compiler/rustc_ast_lowering/src/block.rs @@ -44,17 +44,11 @@ impl<'hir> LoweringContext<'_, 'hir> { stmts.push(hir::Stmt { hir_id, kind, span }); } StmtKind::Item(it) => { - stmts.extend(self.lower_item_ref(it).into_iter().enumerate().map( - |(i, item_id)| { - let hir_id = match i { - 0 => self.lower_node_id(s.id), - _ => self.next_id(), - }; - let kind = hir::StmtKind::Item(item_id); - let span = self.lower_span(s.span); - hir::Stmt { hir_id, kind, span } - }, - )); + let item_id = self.lower_item_ref(it); + let hir_id = self.lower_node_id(s.id); + let kind = hir::StmtKind::Item(item_id); + let span = self.lower_span(s.span); + stmts.push(hir::Stmt { hir_id, kind, span }); } StmtKind::Expr(e) => { let e = self.lower_expr(e); diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index f0b292d3179da..86651431c06a0 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -3,7 +3,6 @@ use std::ops::ControlFlow; use std::sync::Arc; use rustc_ast::*; -use rustc_ast_pretty::pprust::expr_to_string; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::msg; use rustc_hir as hir; @@ -445,13 +444,16 @@ impl<'hir> LoweringContext<'_, 'hir> { let mut invalid_expr_error = |tcx: TyCtxt<'_>, span| { // Avoid emitting the error multiple times. if error.is_none() { + let sm = tcx.sess.source_map(); let mut const_args = vec![]; let mut other_args = vec![]; for (idx, arg) in args.iter().enumerate() { - if legacy_args_idx.contains(&idx) { - const_args.push(format!("{{ {} }}", expr_to_string(arg))); - } else { - other_args.push(expr_to_string(arg)); + if let Ok(arg) = sm.span_to_snippet(arg.span) { + if legacy_args_idx.contains(&idx) { + const_args.push(format!("{{ {} }}", arg)); + } else { + other_args.push(arg); + } } } let suggestion = UseConstGenericArg { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 2195581eccec3..da091f1ecd050 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -3,56 +3,32 @@ use std::mem; use rustc_abi::ExternAbi; use rustc_ast::visit::AssocCtxt; use rustc_ast::*; -use rustc_data_structures::fx::FxIndexMap; use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err}; use rustc_hir::attrs::{AttributeKind, EiiImplResolution}; use rustc_hir::def::{DefKind, PerNS, Res}; -use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId}; +use rustc_hir::def_id::CRATE_DEF_ID; use rustc_hir::{ self as hir, HirId, ImplItemImplKind, LifetimeSource, PredicateOrigin, Target, find_attr, }; -use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::span_bug; use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; use rustc_span::def_id::DefId; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym}; -use smallvec::{SmallVec, smallvec}; +use smallvec::SmallVec; use thin_vec::ThinVec; use tracing::instrument; use super::errors::{InvalidAbi, InvalidAbiSuggestion, TupleStructWithDefault, UnionWithDefault}; use super::stability::{enabled_names, gate_unstable_abi}; use super::{ - AstOwner, FnDeclKind, GenericArgsMode, ImplTraitContext, ImplTraitPosition, LoweringContext, - ParamMode, RelaxedBoundForbiddenReason, RelaxedBoundPolicy, ResolverAstLoweringExt, + FnDeclKind, GenericArgsMode, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode, + RelaxedBoundForbiddenReason, RelaxedBoundPolicy, ResolverAstLoweringExt, }; -/// Wraps either IndexVec (during `hir_crate`), which acts like a primary -/// storage for most of the MaybeOwners, or FxIndexMap during delayed AST -> HIR -/// lowering of delegations (`lower_delayed_owner`), -/// in this case we can not modify already created IndexVec, so we use other map. -pub(super) enum Owners<'a, 'hir> { - IndexVec(&'a mut IndexVec>), - Map(&'a mut FxIndexMap>), -} - -impl<'hir> Owners<'_, 'hir> { - fn get_or_insert_mut(&mut self, def_id: LocalDefId) -> &mut hir::MaybeOwner<'hir> { - match self { - Owners::IndexVec(index_vec) => { - index_vec.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom) - } - Owners::Map(map) => map.entry(def_id).or_insert(hir::MaybeOwner::Phantom), - } - } -} - pub(super) struct ItemLowerer<'a, 'hir> { pub(super) tcx: TyCtxt<'hir>, pub(super) resolver: &'a ResolverAstLowering<'hir>, - pub(super) ast_index: &'a IndexSlice>, - pub(super) owners: Owners<'a, 'hir>, } /// When we have a ty alias we *may* have two where clauses. To give the best diagnostics, we set the span @@ -78,47 +54,43 @@ impl<'hir> ItemLowerer<'_, 'hir> { fn with_lctx( &mut self, owner: NodeId, - f: impl for<'a> FnOnce(&mut LoweringContext<'a, 'hir>) -> hir::OwnerNode<'hir>, - ) { - let mut lctx = LoweringContext::new(self.tcx, self.resolver); - lctx.with_hir_id_owner(owner, |lctx| f(lctx)); - - for (def_id, info) in lctx.children { - let owner = self.owners.get_or_insert_mut(def_id); - assert!( - matches!(owner, hir::MaybeOwner::Phantom), - "duplicate copy of {def_id:?} in lctx.children" - ); - *owner = info; - } + f: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::OwnerNode<'hir>, + ) -> hir::MaybeOwner<'hir> { + let mut lctx = LoweringContext::new(self.tcx, self.resolver, owner); + + let item = f(&mut lctx); + debug_assert_eq!(lctx.current_hir_id_owner, item.def_id()); + + let info = lctx.make_owner_info(item); + + hir::MaybeOwner::Owner(lctx.arena.alloc(info)) } - pub(super) fn lower_node(&mut self, def_id: LocalDefId) { - let owner = self.owners.get_or_insert_mut(def_id); - if let hir::MaybeOwner::Phantom = owner { - let node = self.ast_index[def_id]; - match node { - AstOwner::NonOwner => {} - AstOwner::Crate(c) => { - assert_eq!(self.resolver.local_def_id(CRATE_NODE_ID), CRATE_DEF_ID); - self.with_lctx(CRATE_NODE_ID, |lctx| { - let module = lctx.lower_mod(&c.items, &c.spans); - // FIXME(jdonszelman): is dummy span ever a problem here? - lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, DUMMY_SP, Target::Crate); - hir::OwnerNode::Crate(module) - }) - } - AstOwner::Item(item) => { - self.with_lctx(item.id, |lctx| hir::OwnerNode::Item(lctx.lower_item(item))) - } - AstOwner::AssocItem(item, ctxt) => { - self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt)) - } - AstOwner::ForeignItem(item) => self.with_lctx(item.id, |lctx| { - hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item)) - }), - } - } + #[instrument(level = "debug", skip(self, c))] + pub(super) fn lower_crate(&mut self, c: &Crate) -> hir::MaybeOwner<'hir> { + debug_assert_eq!(self.resolver.node_id_to_def_id[&CRATE_NODE_ID], CRATE_DEF_ID); + self.with_lctx(CRATE_NODE_ID, |lctx| { + let module = lctx.lower_mod(&c.items, &c.spans); + lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, c.spans.inner_span, Target::Crate); + hir::OwnerNode::Crate(module) + }) + } + + #[instrument(level = "debug", skip(self))] + pub(super) fn lower_item(&mut self, item: &Item) -> hir::MaybeOwner<'hir> { + self.with_lctx(item.id, |lctx| hir::OwnerNode::Item(lctx.lower_item(item))) + } + + pub(super) fn lower_trait_item(&mut self, item: &AssocItem) -> hir::MaybeOwner<'hir> { + self.with_lctx(item.id, |lctx| hir::OwnerNode::TraitItem(lctx.lower_trait_item(item))) + } + + pub(super) fn lower_impl_item(&mut self, item: &AssocItem) -> hir::MaybeOwner<'hir> { + self.with_lctx(item.id, |lctx| hir::OwnerNode::ImplItem(lctx.lower_impl_item(item))) + } + + pub(super) fn lower_foreign_item(&mut self, item: &ForeignItem) -> hir::MaybeOwner<'hir> { + self.with_lctx(item.id, |lctx| hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item))) } } @@ -133,28 +105,12 @@ impl<'hir> LoweringContext<'_, 'hir> { inner_span: self.lower_span(spans.inner_span), inject_use_span: self.lower_span(spans.inject_use_span), }, - item_ids: self.arena.alloc_from_iter(items.iter().flat_map(|x| self.lower_item_ref(x))), + item_ids: self.arena.alloc_from_iter(items.iter().map(|x| self.lower_item_ref(x))), }) } - pub(super) fn lower_item_ref(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> { - let mut node_ids = smallvec![hir::ItemId { owner_id: self.owner_id(i.id) }]; - if let ItemKind::Use(use_tree) = &i.kind { - self.lower_item_id_use_tree(use_tree, &mut node_ids); - } - node_ids - } - - fn lower_item_id_use_tree(&mut self, tree: &UseTree, vec: &mut SmallVec<[hir::ItemId; 1]>) { - match &tree.kind { - UseTreeKind::Nested { items, .. } => { - for &(ref nested, id) in items { - vec.push(hir::ItemId { owner_id: self.owner_id(id) }); - self.lower_item_id_use_tree(nested, vec); - } - } - UseTreeKind::Simple(..) | UseTreeKind::Glob(_) => {} - } + pub(super) fn lower_item_ref(&mut self, i: &Item) -> hir::ItemId { + hir::ItemId { owner_id: self.owner_id(i.id) } } fn lower_eii_decl( @@ -252,8 +208,9 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> { + let owner_id = self.current_hir_id_owner; + let hir_id: HirId = owner_id.into(); let vis_span = self.lower_span(i.vis.span); - let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id); let extra_hir_attributes = self.generate_extra_attrs_for_item_kind(i.id, &i.kind); let attrs = self.lower_attrs_with_extra( @@ -266,7 +223,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let kind = self.lower_item_kind(i.span, i.id, hir_id, attrs, vis_span, &i.kind); let item = hir::Item { - owner_id: hir_id.expect_owner(), + owner_id, kind, vis_span, span: self.lower_span(i.span), @@ -779,21 +736,9 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) -> hir::OwnerNode<'hir> { - // Evaluate with the lifetimes in `params` in-scope. - // This is used to track which lifetimes have already been defined, - // and which need to be replicated when lowering an async fn. - match ctxt { - AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item)), - AssocCtxt::Impl { of_trait } => { - hir::OwnerNode::ImplItem(self.lower_impl_item(item, of_trait)) - } - } - } - fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> { - let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id); - let owner_id = hir_id.expect_owner(); + let owner_id = self.current_hir_id_owner; + let hir_id: HirId = owner_id.into(); let attrs = self.lower_attrs(hir_id, &i.attrs, i.span, Target::from_foreign_item_kind(&i.kind)); let (ident, kind) = match &i.kind { @@ -973,14 +918,14 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> { - let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id); + let trait_item_def_id = self.current_hir_id_owner; + let hir_id: HirId = trait_item_def_id.into(); let attrs = self.lower_attrs( hir_id, &i.attrs, i.span, Target::from_assoc_item_kind(&i.kind, AssocCtxt::Trait), ); - let trait_item_def_id = hir_id.expect_owner(); let (ident, generics, kind, has_value) = match &i.kind { AssocItemKind::Const(box ConstItem { @@ -1202,16 +1147,17 @@ impl<'hir> LoweringContext<'_, 'hir> { }) } - fn lower_impl_item( - &mut self, - i: &AssocItem, - is_in_trait_impl: bool, - ) -> &'hir hir::ImplItem<'hir> { + fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> { + let owner_id = self.current_hir_id_owner; + let hir_id: HirId = owner_id.into(); + let parent_id = self.tcx.local_parent(owner_id.def_id); + let is_in_trait_impl = + matches!(self.tcx.def_kind(parent_id), DefKind::Impl { of_trait: true }); + // Since `default impl` is not yet implemented, this is always true in impls. let has_value = true; let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value, || hir::Defaultness::Final); - let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id); let attrs = self.lower_attrs( hir_id, &i.attrs, @@ -1329,7 +1275,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let span = self.lower_span(i.span); let item = hir::ImplItem { - owner_id: hir_id.expect_owner(), + owner_id, ident: self.lower_ident(ident), generics, impl_kind: if is_in_trait_impl { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 5188fb8d6aada..da6f79c24d4f3 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -38,39 +38,37 @@ use std::mem; use std::sync::Arc; +use rustc_ast::mut_visit::{self, MutVisitor}; use rustc_ast::node_id::NodeMap; -use rustc_ast::visit::Visitor; +use rustc_ast::visit::{self, Visitor}; use rustc_ast::{self as ast, *}; use rustc_attr_parsing::{AttributeParser, EmitAttribute, Late, OmitDoc}; -use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::steal::Steal; use rustc_data_structures::tagged_ptr::TaggedRef; +use rustc_data_structures::unord::ExtendUnord; use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle}; use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; -use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId}; +use rustc_hir::def_id::{LOCAL_CRATE, LocalDefId, LocalDefIdMap}; use rustc_hir::definitions::PerParentDisambiguatorState; use rustc_hir::lints::{AttributeLint, DelayedLint, DynAttribute}; use rustc_hir::{ self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource, LifetimeSyntax, ParamName, Target, TraitCandidate, find_attr, }; -use rustc_index::{Idx, IndexSlice, IndexVec}; +use rustc_index::{Idx, IndexVec}; use rustc_macros::extension; -use rustc_middle::hir::{self as mid_hir}; use rustc_middle::span_bug; use rustc_middle::ty::{DelegationInfo, ResolverAstLowering, TyCtxt}; use rustc_session::parse::add_feature_diagnostics; use rustc_span::symbol::{Ident, Symbol, kw, sym}; use rustc_span::{DUMMY_SP, DesugaringKind, Span}; -use smallvec::SmallVec; +use smallvec::{SmallVec, smallvec}; use thin_vec::ThinVec; use tracing::{debug, instrument, trace}; use crate::errors::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait}; -use crate::item::Owners; macro_rules! arena_vec { ($this:expr; $($x:expr),*) => ( @@ -106,7 +104,7 @@ struct LoweringContext<'a, 'hir> { /// Attributes inside the owner being lowered. attrs: SortedMap, /// Collect items that were created by lowering the current owner. - children: Vec<(LocalDefId, hir::MaybeOwner<'hir>)>, + children: LocalDefIdMap>, contract_ensures: Option<(Span, Ident, HirId)>, @@ -164,25 +162,32 @@ struct LoweringContext<'a, 'hir> { } impl<'a, 'hir> LoweringContext<'a, 'hir> { - fn new(tcx: TyCtxt<'hir>, resolver: &'a ResolverAstLowering<'hir>) -> Self { + fn new(tcx: TyCtxt<'hir>, resolver: &'a ResolverAstLowering<'hir>, owner: NodeId) -> Self { let registered_tools = tcx.registered_tools(()).iter().map(|x| x.name).collect(); + let current_hir_id_owner = hir::OwnerId { def_id: resolver.node_id_to_def_id[&owner] }; + let current_disambiguator = resolver + .disambiguators + .get(¤t_hir_id_owner.def_id) + .map(|s| s.steal()) + .unwrap_or_else(|| PerParentDisambiguatorState::new(current_hir_id_owner.def_id)); + Self { tcx, resolver, - current_disambiguator: Default::default(), + current_disambiguator, arena: tcx.hir_arena, // HirId handling. bodies: Vec::new(), define_opaque: None, attrs: SortedMap::default(), - children: Vec::default(), + children: LocalDefIdMap::default(), contract_ensures: None, - current_hir_id_owner: hir::CRATE_OWNER_ID, - item_local_id_counter: hir::ItemLocalId::ZERO, + current_hir_id_owner, + item_local_id_counter: hir::ItemLocalId::new(1), ident_and_label_to_local_id: Default::default(), #[cfg(debug_assertions)] - node_id_to_local_id: Default::default(), + node_id_to_local_id: [(owner, hir::ItemLocalId::ZERO)].into_iter().collect(), trait_map: Default::default(), next_node_id: resolver.next_node_id, node_id_to_def_id: NodeMap::default(), @@ -313,14 +318,6 @@ impl<'tcx> ResolverAstLowering<'tcx> { self.delegation_infos.get(&id) } - fn opt_local_def_id(&self, id: NodeId) -> Option { - self.node_id_to_def_id.get(&id).copied() - } - - fn local_def_id(&self, id: NodeId) -> LocalDefId { - self.opt_local_def_id(id).expect("must have def_id") - } - fn lifetime_elision_allowed(&self, id: NodeId) -> bool { self.lifetime_elision_allowed.contains(&id) } @@ -442,15 +439,6 @@ enum FnDeclKind { Impl, } -#[derive(Copy, Clone)] -enum AstOwner<'a> { - NonOwner, - Crate(&'a ast::Crate), - Item(&'a ast::Item), - AssocItem(&'a ast::AssocItem, visit::AssocCtxt), - ForeignItem(&'a ast::ForeignItem), -} - #[derive(Copy, Clone, Debug)] enum TryBlockScope { /// There isn't a `try` block, so a `?` will use `return`. @@ -463,137 +451,209 @@ enum TryBlockScope { Heterogeneous(HirId), } -fn index_crate<'a, 'b>( - resolver: &'b ResolverAstLowering<'b>, - krate: &'a Crate, -) -> IndexVec> { - let mut indexer = Indexer { resolver, index: IndexVec::new() }; - *indexer.index.ensure_contains_elem(CRATE_DEF_ID, || AstOwner::NonOwner) = - AstOwner::Crate(krate); - visit::walk_crate(&mut indexer, krate); +pub fn index_ast<'tcx>( + tcx: TyCtxt<'tcx>, + (): (), +) -> IndexVec>, AstOwner)>> { + // Queries that borrow `resolver_for_lowering`. + tcx.ensure_done().output_filenames(()); + tcx.ensure_done().early_lint_checks(()); + tcx.ensure_done().get_lang_items(()); + tcx.ensure_done().debugger_visualizers(LOCAL_CRATE); + + let (resolver, krate) = tcx.resolver_for_lowering(); + let mut resolver = resolver.steal(); + let mut krate = krate.steal(); - return indexer.index; + let mut indexer = Indexer { + node_id_to_def_id: &resolver.node_id_to_def_id, + index: IndexVec::new(), + next_node_id: resolver.next_node_id, + }; + indexer.visit_crate(&mut krate); + indexer.insert(CRATE_NODE_ID, AstOwner::Crate(Box::new(krate))); + resolver.next_node_id = indexer.next_node_id; + + let index = indexer.index; + let resolver = Arc::new(resolver); + let index = index.into_iter().map(|owner| Steal::new((resolver.clone(), owner))).collect(); + return index; + + struct Indexer<'s> { + node_id_to_def_id: &'s NodeMap, + index: IndexVec, + next_node_id: NodeId, + } + + impl Indexer<'_> { + fn insert(&mut self, id: NodeId, node: AstOwner) { + let def_id = self.node_id_to_def_id[&id]; + self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner); + self.index[def_id] = node; + } - struct Indexer<'a, 'b> { - resolver: &'b ResolverAstLowering<'b>, - index: IndexVec>, + fn make_dummy( + &mut self, + id: NodeId, + span: Span, + dummy: impl FnOnce(Box) -> K, + ) -> Box> { + use rustc_ast::token::Delimiter; + use rustc_ast::tokenstream::{DelimSpan, TokenStream}; + use thin_vec::thin_vec; + + Box::new(Item { + attrs: AttrVec::default(), + id, + span, + vis: Visibility { kind: VisibilityKind::Public, span, tokens: None }, + // Lacking a better choice, we replace the contents with a macro call. + // Unexpanded macros should never reach lowering, so this is not confusing. + kind: dummy(Box::new(MacCall { + path: Path { span, segments: thin_vec![], tokens: None }, + args: Box::new(DelimArgs { + dspan: DelimSpan::from_single(span), + delim: Delimiter::Parenthesis, + tokens: TokenStream::new(Vec::new()), + }), + })), + tokens: None, + }) + } + + fn replace_with_dummy( + &mut self, + item: &mut ast::Item, + dummy: impl FnOnce(Box) -> K, + node: impl FnOnce(Box>) -> AstOwner, + ) { + let dummy = self.make_dummy(item.id, item.span, dummy); + let item = std::mem::replace(item, *dummy); + self.insert(item.id, node(Box::new(item))); + } + + #[tracing::instrument(level = "trace", skip(self))] + fn visit_item_id_use_tree( + &mut self, + tree: &UseTree, + parent: LocalDefId, + items: &mut SmallVec<[Box; 1]>, + ) { + match tree.kind { + UseTreeKind::Glob(_) | UseTreeKind::Simple(_) => {} + UseTreeKind::Nested { items: ref nested_vec, span } => { + for &(ref nested, id) in nested_vec { + self.insert(id, AstOwner::Synthetic(parent)); + items.push(self.make_dummy(id, span, ItemKind::MacCall)); + + let def_id = self.node_id_to_def_id[&id]; + self.visit_item_id_use_tree(nested, def_id, items); + } + } + } + } } - impl<'a, 'b> visit::Visitor<'a> for Indexer<'a, 'b> { - fn visit_attribute(&mut self, _: &'a Attribute) { + impl MutVisitor for Indexer<'_> { + fn visit_attribute(&mut self, _: &mut Attribute) { // We do not want to lower expressions that appear in attributes, // as they are not accessible to the rest of the HIR. } - fn visit_item(&mut self, item: &'a ast::Item) { - let def_id = self.resolver.local_def_id(item.id); - *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = AstOwner::Item(item); - visit::walk_item(self, item) + fn flat_map_item(&mut self, mut item: Box) -> SmallVec<[Box; 1]> { + let def_id = self.node_id_to_def_id[&item.id]; + mut_visit::walk_item(self, &mut *item); + let dummy = self.make_dummy(item.id, item.span, ItemKind::MacCall); + let mut items = smallvec![dummy]; + if let ItemKind::Use(ref use_tree) = item.kind { + self.visit_item_id_use_tree(use_tree, def_id, &mut items); + } + self.insert(item.id, AstOwner::Item(item)); + items + } + + fn flat_map_stmt(&mut self, stmt: Stmt) -> SmallVec<[Stmt; 1]> { + let Stmt { id, span, kind } = stmt; + let mut id = Some(id); + mut_visit::walk_flat_map_stmt_kind(self, kind) + .into_iter() + .map(|kind| { + let id = id.take().unwrap_or_else(|| { + let next = self.next_node_id; + self.next_node_id.increment_by(1); + next + }); + Stmt { id, kind, span } + }) + .collect() } - fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: visit::AssocCtxt) { - let def_id = self.resolver.local_def_id(item.id); - *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = - AstOwner::AssocItem(item, ctxt); - visit::walk_assoc_item(self, item, ctxt); + fn visit_assoc_item(&mut self, item: &mut AssocItem, ctxt: visit::AssocCtxt) { + mut_visit::walk_assoc_item(self, item, ctxt); + match ctxt { + visit::AssocCtxt::Trait => { + self.replace_with_dummy(item, AssocItemKind::MacCall, AstOwner::TraitItem) + } + visit::AssocCtxt::Impl { .. } => { + self.replace_with_dummy(item, AssocItemKind::MacCall, AstOwner::ImplItem) + } + } } - fn visit_foreign_item(&mut self, item: &'a ast::ForeignItem) { - let def_id = self.resolver.local_def_id(item.id); - *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = - AstOwner::ForeignItem(item); - visit::walk_item(self, item); + fn visit_foreign_item(&mut self, item: &mut ForeignItem) { + mut_visit::walk_item(self, item); + self.replace_with_dummy(item, ForeignItemKind::MacCall, AstOwner::ForeignItem); } } } -/// Compute the hash for the HIR of the full crate. -/// This hash will then be part of the crate_hash which is stored in the metadata. -fn compute_hir_hash( - tcx: TyCtxt<'_>, - owners: &IndexSlice>, -) -> Fingerprint { - let mut hir_body_nodes: Vec<_> = owners - .iter_enumerated() - .filter_map(|(def_id, info)| { - let info = info.as_owner()?; - let def_path_hash = tcx.hir_def_path_hash(def_id); - Some((def_path_hash, info)) - }) - .collect(); - hir_body_nodes.sort_unstable_by_key(|bn| bn.0); - - tcx.with_stable_hashing_context(|mut hcx| { - let mut stable_hasher = StableHasher::new(); - hir_body_nodes.hash_stable(&mut hcx, &mut stable_hasher); - stable_hasher.finish() - }) -} - -pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { +#[instrument(level = "trace", skip(tcx))] +pub fn lower_to_hir(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::MaybeOwner<'_> { // Queries that borrow `resolver_for_lowering`. tcx.ensure_done().output_filenames(()); tcx.ensure_done().early_lint_checks(()); tcx.ensure_done().debugger_visualizers(LOCAL_CRATE); tcx.ensure_done().get_lang_items(()); - let (resolver, krate) = tcx.resolver_for_lowering().steal(); - - let ast_index = index_crate(&resolver, &krate); - let mut owners = IndexVec::from_fn_n( - |_| hir::MaybeOwner::Phantom, - tcx.definitions_untracked().def_index_count(), - ); + let ast_index = tcx.index_ast(()); + let resolver_and_node = ast_index.get(def_id).map(Steal::steal); + + let fallback_to_parent = |parent_id| { + // The item did not exist in the AST, it was created by its parent. + let mut parent_info = tcx.lower_to_hir(parent_id); + if let hir::MaybeOwner::NonOwner(hir_id) = parent_info { + parent_info = tcx.lower_to_hir(hir_id.owner); + } - let mut lowerer = item::ItemLowerer { - tcx, - resolver: &resolver, - ast_index: &ast_index, - owners: Owners::IndexVec(&mut owners), + let parent_info = parent_info.unwrap(); + *parent_info.children.get(&def_id).unwrap_or_else(|| { + panic!( + "{:?} does not appear in children of {:?}", + def_id, + parent_info.nodes.node().def_id() + ) + }) }; - let mut delayed_ids: FxIndexSet = Default::default(); - - for def_id in ast_index.indices() { - match &ast_index[def_id] { - AstOwner::Item(Item { kind: ItemKind::Delegation { .. }, .. }) - | AstOwner::AssocItem(Item { kind: AssocItemKind::Delegation { .. }, .. }, _) => { - delayed_ids.insert(def_id); - } - _ => lowerer.lower_node(def_id), - }; - } - - // Don't hash unless necessary, because it's expensive. - let opt_hir_hash = - if tcx.needs_crate_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None }; - - let delayed_resolver = Steal::new((resolver, krate)); - mid_hir::Crate::new(owners, delayed_ids, delayed_resolver, opt_hir_hash) -} - -/// Lowers an AST owner corresponding to `def_id`, now only delegations are lowered this way. -pub fn lower_delayed_owner(tcx: TyCtxt<'_>, def_id: LocalDefId) { - let krate = tcx.hir_crate(()); - - let (resolver, krate) = &*krate.delayed_resolver.borrow(); - - // FIXME!!!(fn_delegation): make ast index lifetime same as resolver, - // as it is too bad to reindex whole crate on each delegation lowering. - let ast_index = index_crate(resolver, krate); + let Some((resolver, node)) = resolver_and_node else { + return fallback_to_parent(tcx.local_parent(def_id)); + }; - let mut map = Default::default(); - let mut lowerer = item::ItemLowerer { - tcx, - resolver: &resolver, - ast_index: &ast_index, - owners: Owners::Map(&mut map), + let mut item_lowerer = item::ItemLowerer { tcx, resolver: &*resolver }; + + let item = match &node { + // The item existed in the AST. + AstOwner::Crate(c) => item_lowerer.lower_crate(&c), + AstOwner::Item(item) => item_lowerer.lower_item(&item), + AstOwner::TraitItem(item) => item_lowerer.lower_trait_item(&item), + AstOwner::ImplItem(item) => item_lowerer.lower_impl_item(&item), + AstOwner::ForeignItem(item) => item_lowerer.lower_foreign_item(&item), + AstOwner::Synthetic(parent_id) => fallback_to_parent(*parent_id), + AstOwner::NonOwner => fallback_to_parent(tcx.local_parent(def_id)), }; - lowerer.lower_node(def_id); + tcx.sess.time("drop_ast", || std::mem::drop(node)); - for (child_def_id, owner) in map { - tcx.feed_delayed_owner(child_def_id, owner); - } + item } #[derive(Copy, Clone, PartialEq, Debug)] @@ -662,6 +722,7 @@ impl<'hir> LoweringContext<'_, 'hir> { /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name /// resolver (if any). + #[instrument(level = "trace", skip(self), ret)] fn opt_local_def_id(&self, node: NodeId) -> Option { self.node_id_to_def_id .get(&node) @@ -722,6 +783,7 @@ impl<'hir> LoweringContext<'_, 'hir> { 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); let current_delayed_lints = std::mem::take(&mut self.delayed_lints); + let current_children = std::mem::take(&mut self.children); // Do not reset `next_node_id` and `node_id_to_def_id`: // we want `f` to be able to refer to the `LocalDefId`s that the caller created. @@ -757,9 +819,11 @@ impl<'hir> LoweringContext<'_, 'hir> { self.impl_trait_defs = current_impl_trait_defs; self.impl_trait_bounds = current_impl_trait_bounds; self.delayed_lints = current_delayed_lints; + self.children = current_children; + self.children.extend_unord(info.children.items().map(|(&def_id, &info)| (def_id, info))); - debug_assert!(!self.children.iter().any(|(id, _)| id == &owner_id.def_id)); - self.children.push((owner_id.def_id, hir::MaybeOwner::Owner(info))); + debug_assert!(!self.children.contains_key(&owner_id.def_id)); + self.children.insert(owner_id.def_id, hir::MaybeOwner::Owner(info)); } fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInfo<'hir> { @@ -768,6 +832,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let define_opaque = std::mem::take(&mut self.define_opaque); let trait_map = std::mem::take(&mut self.trait_map); let delayed_lints = std::mem::take(&mut self.delayed_lints).into_boxed_slice(); + let children = std::mem::take(&mut self.children); #[cfg(debug_assertions)] for (id, attrs) in attrs.iter() { @@ -781,14 +846,37 @@ impl<'hir> LoweringContext<'_, 'hir> { let bodies = SortedMap::from_presorted_elements(bodies); // Don't hash unless necessary, because it's expensive. - let rustc_middle::hir::Hashes { opt_hash_including_bodies, attrs_hash } = + let rustc_middle::hir::Hashes { bodies_hash, attrs_hash } = self.tcx.hash_owner_nodes(node, &bodies, &attrs, define_opaque); let num_nodes = self.item_local_id_counter.as_usize(); let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes); - let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies }; + let nodes = hir::OwnerNodes { opt_hash: bodies_hash, nodes, bodies }; let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash, define_opaque }; - self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map, delayed_lints }) + let opt_hash = if self.tcx.needs_crate_hash() { + Some(self.tcx.with_stable_hashing_context(|mut hcx| { + let mut stable_hasher = StableHasher::new(); + bodies_hash.unwrap().hash_stable(&mut hcx, &mut stable_hasher); + attrs_hash.unwrap().hash_stable(&mut hcx, &mut stable_hasher); + // Do not hash delayed_lints. + parenting.hash_stable(&mut hcx, &mut stable_hasher); + trait_map.hash_stable(&mut hcx, &mut stable_hasher); + children.hash_stable(&mut hcx, &mut stable_hasher); + stable_hasher.finish() + })) + } else { + None + }; + + self.arena.alloc(hir::OwnerInfo { + opt_hash, + nodes, + parenting, + attrs, + trait_map, + delayed_lints, + children, + }) } /// This method allocates a new `HirId` for the given `NodeId`. @@ -807,7 +895,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let hir_id = HirId { owner, local_id }; if let Some(def_id) = self.opt_local_def_id(ast_node_id) { - self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id))); + self.children.insert(def_id, hir::MaybeOwner::NonOwner(hir_id)); } if let Some(traits) = self.resolver.trait_map.get(&ast_node_id) { diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 79b6fc59978f3..230c56e89a7e3 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -212,7 +212,7 @@ impl<'tcx> PrintExtra<'tcx> { { match self { PrintExtra::AfterParsing { krate, .. } => f(krate), - PrintExtra::NeedsAstMap { tcx } => f(&tcx.resolver_for_lowering().borrow().1), + PrintExtra::NeedsAstMap { tcx } => f(&tcx.resolver_for_lowering().1.borrow()), } } @@ -262,7 +262,7 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { } AstTreeExpanded => { debug!("pretty-printing expanded AST"); - format!("{:#?}", ex.tcx().resolver_for_lowering().borrow().1) + format!("{:#?}", ex.tcx().resolver_for_lowering().1.borrow()) } Hir(s) => { debug!("pretty printing HIR {:?}", s); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 5608bd82fdacd..4433d13d09cf6 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -19,6 +19,7 @@ pub use rustc_ast::{ use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::tagged_ptr::TaggedRef; +use rustc_data_structures::unord::UnordMap; use rustc_error_messages::{DiagArgValue, IntoDiagArg}; use rustc_index::IndexVec; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; @@ -1578,7 +1579,7 @@ impl<'tcx> AttributeMap<'tcx> { pub struct OwnerNodes<'tcx> { /// Pre-computed hash of the full HIR. Used in the crate hash. Only present /// when incr. comp. is enabled. - pub opt_hash_including_bodies: Option, + pub opt_hash: Option, /// Full HIR for the current owner. // The zeroth node's parent should never be accessed: the owner's parent is computed by the // hir_owner_parent query. It is set to `ItemLocalId::INVALID` to force an ICE if accidentally @@ -1611,13 +1612,13 @@ impl fmt::Debug for OwnerNodes<'_> { }), ) .field("bodies", &self.bodies) - .field("opt_hash_including_bodies", &self.opt_hash_including_bodies) + .field("opt_hash", &self.opt_hash) .finish() } } /// Full information resulting from lowering an AST node. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug)] pub struct OwnerInfo<'hir> { /// Contents of the HIR. pub nodes: OwnerNodes<'hir>, @@ -1634,8 +1635,11 @@ pub struct OwnerInfo<'hir> { /// /// WARNING: The delayed lints are not hashed as a part of the `OwnerInfo`, and therefore /// should only be accessed in `eval_always` queries. - #[stable_hasher(ignore)] pub delayed_lints: DelayedLints, + /// Owners generated as side-effect by lowering. + pub children: UnordMap>, + // Only present when the crate hash is needed. + pub opt_hash: Option, } impl<'tcx> OwnerInfo<'tcx> { @@ -1649,18 +1653,18 @@ impl<'tcx> OwnerInfo<'tcx> { pub enum MaybeOwner<'tcx> { Owner(&'tcx OwnerInfo<'tcx>), NonOwner(HirId), - /// Used as a placeholder for unused LocalDefId. - Phantom, } impl<'tcx> MaybeOwner<'tcx> { + #[inline] pub fn as_owner(self) -> Option<&'tcx OwnerInfo<'tcx>> { match self { MaybeOwner::Owner(i) => Some(i), - MaybeOwner::NonOwner(_) | MaybeOwner::Phantom => None, + MaybeOwner::NonOwner(_) => None, } } + #[inline] pub fn unwrap(self) -> &'tcx OwnerInfo<'tcx> { self.as_owner().unwrap_or_else(|| panic!("Not a HIR owner")) } diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs index 3a10f790cd5cc..4a721a5d29fdb 100644 --- a/compiler/rustc_hir/src/stable_hash_impls.rs +++ b/compiler/rustc_hir/src/stable_hash_impls.rs @@ -4,7 +4,7 @@ use rustc_span::def_id::DefPathHash; use crate::HashIgnoredAttrId; use crate::hir::{ - AttributeMap, BodyId, ForeignItemId, ImplItemId, ItemId, OwnerNodes, TraitItemId, + AttributeMap, BodyId, ForeignItemId, ImplItemId, ItemId, OwnerInfo, OwnerNodes, TraitItemId, }; use crate::hir_id::ItemLocalId; @@ -62,18 +62,17 @@ impl ToStableHashKey for ForeignItemId { // in "DefPath Mode". impl<'tcx, Hcx: HashStableContext> HashStable for OwnerNodes<'tcx> { + #[inline] fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { - // We ignore the `nodes` and `bodies` fields since these refer to information included in - // `hash` which is hashed in the collector and used for the crate hash. - // `local_id_to_def_id` is also ignored because is dependent on the body, then just hashing - // the body satisfies the condition of two nodes being different have different - // `hash_stable` results. - let OwnerNodes { opt_hash_including_bodies, nodes: _, bodies: _ } = *self; - opt_hash_including_bodies.unwrap().hash_stable(hcx, hasher); + // We ignore the other fields since these refer to information included in + // `opt_hash` which is hashed in the collector and used for the crate hash. + let OwnerNodes { opt_hash, .. } = *self; + opt_hash.unwrap().hash_stable(hcx, hasher); } } impl<'tcx, Hcx: HashStableContext> HashStable for AttributeMap<'tcx> { + #[inline] fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { // We ignore the `map` since it refers to information included in `opt_hash` which is // hashed in the collector and used for the crate hash. @@ -82,6 +81,16 @@ impl<'tcx, Hcx: HashStableContext> HashStable for AttributeMap<'tcx> { } } +impl<'tcx, Hcx: HashStableContext> HashStable for OwnerInfo<'tcx> { + #[inline] + fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { + // We ignore the rest since it refers to information included in `opt_hash` which is + // hashed in the collector and used for the crate hash. + let OwnerInfo { opt_hash, .. } = *self; + opt_hash.unwrap().hash_stable(hcx, hasher); + } +} + impl HashStable for HashIgnoredAttrId { fn hash_stable(&self, _hcx: &mut Hcx, _hasher: &mut StableHasher) { /* we don't hash HashIgnoredAttrId, we ignore them */ diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 9c020c35e1429..e30a4a35e5adf 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -23,7 +23,7 @@ use rustc_hir::def_id::{LOCAL_CRATE, StableCrateId, StableCrateIdMap}; use rustc_hir::definitions::Definitions; use rustc_hir::limit::Limit; use rustc_hir::lints::DelayedLint; -use rustc_hir::{Attribute, MaybeOwner, Target, find_attr}; +use rustc_hir::{Attribute, Target, find_attr}; use rustc_incremental::setup_dep_graph; use rustc_lint::{ BufferedEarlyLint, DecorateAttrLint, EarlyCheckNode, LintStore, unerased_lint_store, @@ -401,7 +401,9 @@ fn print_macro_stats(ecx: &ExtCtxt<'_>) { fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) { let sess = tcx.sess; - let (resolver, krate) = &*tcx.resolver_for_lowering().borrow(); + let (resolver, krate) = tcx.resolver_for_lowering(); + let resolver = &*resolver.borrow(); + let krate = &*krate.borrow(); let mut lint_buffer = resolver.lint_buffer.steal(); if sess.opts.unstable_opts.input_stats { @@ -477,7 +479,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) { tcx.registered_tools(()), Some(lint_buffer), rustc_lint::BuiltinCombinedEarlyLintPass::new(), - (&**krate, &*krate.attrs), + (&*krate, &*krate.attrs), ) } @@ -784,7 +786,11 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P fn resolver_for_lowering_raw<'tcx>( tcx: TyCtxt<'tcx>, (): (), -) -> (&'tcx Steal<(ty::ResolverAstLowering<'tcx>, Arc)>, &'tcx ty::ResolverGlobalCtxt) { +) -> ( + &'tcx Steal>, + &'tcx Steal, + &'tcx ty::ResolverGlobalCtxt, +) { let arenas = Resolver::arenas(); let _ = tcx.registered_tools(()); // Uses `crate_for_resolver`. let (krate, pre_configured_attrs) = tcx.crate_for_resolver(()).steal(); @@ -805,8 +811,11 @@ fn resolver_for_lowering_raw<'tcx>( ast_lowering: untracked_resolver_for_lowering, } = resolver.into_outputs(); - let resolutions = tcx.arena.alloc(untracked_resolutions); - (tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, Arc::new(krate)))), resolutions) + ( + tcx.arena.alloc(Steal::new(untracked_resolver_for_lowering)), + tcx.arena.alloc(Steal::new(krate)), + tcx.arena.alloc(untracked_resolutions), + ) } pub fn write_dep_info(tcx: TyCtxt<'_>) { @@ -863,10 +872,10 @@ pub fn write_interface<'tcx>(tcx: TyCtxt<'tcx>) { return; } let _timer = tcx.sess.timer("write_interface"); - let (_, krate) = &*tcx.resolver_for_lowering().borrow(); + let (_, krate) = tcx.resolver_for_lowering(); let krate = rustc_ast_pretty::pprust::print_crate_as_interface( - krate, + &*krate.borrow(), tcx.sess.psess.edition, &tcx.sess.psess.attr_id_generator, ); @@ -880,14 +889,11 @@ pub fn write_interface<'tcx>(tcx: TyCtxt<'tcx>) { pub static DEFAULT_QUERY_PROVIDERS: LazyLock = LazyLock::new(|| { let providers = &mut Providers::default(); providers.queries.analysis = analysis; - providers.queries.hir_crate = rustc_ast_lowering::lower_to_hir; - providers.queries.lower_delayed_owner = rustc_ast_lowering::lower_delayed_owner; - // `delayed_owner` is fed during `lower_delayed_owner`, by default it returns phantom, - // as if this query was not fed it means that `MaybeOwner` does not exist for provided LocalDefId. - providers.queries.delayed_owner = |_, _| MaybeOwner::Phantom; + providers.queries.index_ast = rustc_ast_lowering::index_ast; + providers.queries.lower_to_hir = rustc_ast_lowering::lower_to_hir; providers.queries.resolver_for_lowering_raw = resolver_for_lowering_raw; providers.queries.stripped_cfg_items = |tcx, _| &tcx.resolutions(()).stripped_cfg_items[..]; - providers.queries.resolutions = |tcx, ()| tcx.resolver_for_lowering_raw(()).1; + providers.queries.resolutions = |tcx, ()| tcx.resolver_for_lowering_raw(()).2; providers.queries.early_lint_checks = early_lint_checks; providers.queries.env_var_os = env_var_os; limits::provide(&mut providers.queries); @@ -1060,6 +1066,8 @@ pub fn emit_delayed_lints(tcx: TyCtxt<'_>) { /// Runs all analyses that we guarantee to run, even if errors were reported in earlier analyses. /// This function never fails. fn run_required_analyses(tcx: TyCtxt<'_>) { + tcx.ensure_done().early_lint_checks(()); + if tcx.sess.opts.unstable_opts.input_stats { rustc_passes::input_stats::print_hir_stats(tcx); } diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index de6a105ee2b7b..b94fbcb8c678a 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -31,10 +31,15 @@ macro_rules! arena_types { rustc_hir::def_id::LocalDefId, rustc_middle::ty::DefinitionSiteHiddenType<'tcx>, >, - [] resolver: rustc_data_structures::steal::Steal<( - rustc_middle::ty::ResolverAstLowering<'tcx>, - std::sync::Arc, - )>, + [] resolver: rustc_data_structures::steal::Steal>, + [] index_ast: rustc_index::IndexVec< + rustc_span::def_id::LocalDefId, + rustc_data_structures::steal::Steal<( + std::sync::Arc>, + rustc_ast::AstOwner + )> + >, + [] crate_alone: rustc_data_structures::steal::Steal, [] crate_for_resolver: rustc_data_structures::steal::Steal<(rustc_ast::Crate, rustc_ast::AttrVec)>, [] resolutions: rustc_middle::ty::ResolverGlobalCtxt, [] const_allocs: rustc_middle::mir::interpret::Allocation, diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index d63034ed1d2bb..aade1a5faf91d 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -7,7 +7,7 @@ use rustc_ast::visit::{VisitorResult, walk_list}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::svh::Svh; -use rustc_data_structures::sync::{DynSend, DynSync, par_for_each_in, spawn, try_par_for_each_in}; +use rustc_data_structures::sync::{DynSend, DynSync, par_for_each_in, try_par_for_each_in}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId, LocalModDefId}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; @@ -1134,11 +1134,8 @@ impl<'tcx> pprust_hir::PpAnn for TyCtxt<'tcx> { } pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh { - let krate = tcx.hir_crate(()); - let hir_body_hash = krate.opt_hir_hash.expect("HIR hash missing while computing crate hash"); - + let krate = tcx.hir_crate_items(()); let upstream_crates = upstream_crates(tcx); - let resolutions = tcx.resolutions(()); // We hash the final, remapped names of all local source files so we @@ -1173,7 +1170,12 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh { let crate_hash: Fingerprint = tcx.with_stable_hashing_context(|mut hcx| { let mut stable_hasher = StableHasher::new(); - hir_body_hash.hash_stable(&mut hcx, &mut stable_hasher); + // hir_body_hash + for owner in krate.owners() { + if let Some(info) = tcx.lower_to_hir(owner.def_id).as_owner() { + info.hash_stable(&mut hcx, &mut stable_hasher); + } + } upstream_crates.hash_stable(&mut hcx, &mut stable_hasher); source_file_names.hash_stable(&mut hcx, &mut stable_hasher); debugger_visualizers.hash_stable(&mut hcx, &mut stable_hasher); @@ -1255,25 +1257,7 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod } } -fn force_delayed_owners_lowering(tcx: TyCtxt<'_>) { - let krate = tcx.hir_crate(()); - for &id in &krate.delayed_ids { - tcx.ensure_done().lower_delayed_owner(id); - } - - let (_, krate) = krate.delayed_resolver.steal(); - let prof = tcx.sess.prof.clone(); - - // Drop AST to free memory. It can be expensive so try to drop it on a separate thread. - spawn(move || { - let _timer = prof.verbose_generic_activity("drop_ast"); - drop(krate); - }); -} - pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems { - force_delayed_owners_lowering(tcx); - let mut collector = ItemCollector::new(tcx, true); // A "crate collector" and "module collector" start at a diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 7f82b9161fe61..acce393dcca54 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -6,82 +6,18 @@ pub mod map; pub mod nested_filter; pub mod place; -use std::sync::Arc; - -use rustc_ast::{self as ast}; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{DynSend, DynSync, try_par_for_each_in}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId}; use rustc_hir::*; -use rustc_index::IndexVec; use rustc_macros::{Decodable, Encodable, HashStable}; -use rustc_span::{ErrorGuaranteed, ExpnId, HashStableContext, Span}; +use rustc_span::{ErrorGuaranteed, ExpnId, Span}; use crate::query::Providers; -use crate::ty::{ResolverAstLowering, TyCtxt}; - -/// The top-level data structure that stores the entire contents of -/// the crate currently being compiled. -/// -/// For more details, see the [rustc dev guide]. -/// -/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html -#[derive(Debug)] -pub struct Crate<'hir> { - // This field is private by intention, access it through `owner` method. - owners: IndexVec>, - // Ids of delayed AST owners which are lowered through `lower_delayed_owner` query. - pub delayed_ids: FxIndexSet, - // The resolver and AST crate which are set in the end of the `hir_crate` query - // and then stolen and dropped in `force_delayed_owners_lowering`. - pub delayed_resolver: Steal<(ResolverAstLowering<'hir>, Arc)>, - // Only present when incr. comp. is enabled. - pub opt_hir_hash: Option, -} - -impl<'hir> Crate<'hir> { - pub fn new( - owners: IndexVec>, - delayed_ids: FxIndexSet, - delayed_resolver: Steal<(ResolverAstLowering<'hir>, Arc)>, - opt_hir_hash: Option, - ) -> Crate<'hir> { - Crate { owners, delayed_ids, delayed_resolver, opt_hir_hash } - } - - /// Serves as an entry point for getting `MaybeOwner`. As owner can either be in - /// `owners` of `hir_crate` or it can be delayed AST owner (i.e., delegations) - /// we need to firstly check in `hir_crate` and then delayed AST owners. - /// This method can be invoked when not all delayed AST owners are lowered. - pub fn owner(&self, tcx: TyCtxt<'hir>, def_id: LocalDefId) -> MaybeOwner<'hir> { - // Delayed LocalDefId can be in `self.owners` if there exists non-delayed LocalDefId - // which is greater than delayed LocalDefId, we use IndexVec for owners, - // so we will call ensure_contains_elem which will grow it. - if let Some(owner) = self.owners.get(def_id) - && (self.delayed_ids.is_empty() || !matches!(owner, MaybeOwner::Phantom)) - { - return *owner; - } - - if self.delayed_ids.contains(&def_id) { - tcx.ensure_done().lower_delayed_owner(def_id); - } - - tcx.delayed_owner(def_id) - } -} - -impl HashStable for Crate<'_> { - fn hash_stable(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { - let Crate { opt_hir_hash, .. } = self; - opt_hir_hash.unwrap().hash_stable(hcx, hasher) - } -} +use crate::ty::TyCtxt; /// Gather the LocalDefId for each item-like within a module, including items contained within /// bodies. The Ids are in visitor order. This is used to partition a pass between modules. @@ -238,7 +174,7 @@ impl<'tcx> TyCtxt<'tcx> { define_opaque: Option<&[(Span, LocalDefId)]>, ) -> Hashes { if !self.needs_crate_hash() { - return Hashes { opt_hash_including_bodies: None, attrs_hash: None }; + return Hashes { bodies_hash: None, attrs_hash: None }; } self.with_stable_hashing_context(|mut hcx| { @@ -256,7 +192,7 @@ impl<'tcx> TyCtxt<'tcx> { let h2 = stable_hasher.finish(); - Hashes { opt_hash_including_bodies: Some(h1), attrs_hash: Some(h2) } + Hashes { bodies_hash: Some(h1), attrs_hash: Some(h2) } }) } @@ -422,8 +358,7 @@ impl<'tcx> TyCtxt<'tcx> { HirId { owner: parent_owner_id, local_id: self - .hir_crate(()) - .owner(self, parent_owner_id.def_id) + .lower_to_hir(parent_owner_id.def_id) .unwrap() .parenting .get(&owner_id.def_id) @@ -448,7 +383,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Hashes computed by [`TyCtxt::hash_owner_nodes`] if necessary. #[derive(Clone, Copy, Debug)] pub struct Hashes { - pub opt_hash_including_bodies: Option, + pub bodies_hash: Option, pub attrs_hash: Option, } @@ -456,19 +391,16 @@ pub fn provide(providers: &mut Providers) { providers.hir_crate_items = map::hir_crate_items; providers.crate_hash = map::crate_hash; providers.hir_module_items = map::hir_module_items; - providers.local_def_id_to_hir_id = |tcx, def_id| match tcx.hir_crate(()).owner(tcx, def_id) { + providers.local_def_id_to_hir_id = |tcx, def_id| match tcx.lower_to_hir(def_id) { MaybeOwner::Owner(_) => HirId::make_owner(def_id), MaybeOwner::NonOwner(hir_id) => hir_id, - MaybeOwner::Phantom => bug!("No HirId for {:?}", def_id), }; - providers.opt_hir_owner_nodes = - |tcx, id| tcx.hir_crate(()).owner(tcx, id).as_owner().map(|i| &i.nodes); + providers.opt_hir_owner_nodes = |tcx, id| tcx.lower_to_hir(id).as_owner().map(|i| &i.nodes); providers.hir_owner_parent_q = |tcx, owner_id| tcx.hir_owner_parent_impl(owner_id); - providers.hir_attr_map = |tcx, id| { - tcx.hir_crate(()).owner(tcx, id.def_id).as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs) - }; + providers.hir_attr_map = + |tcx, id| tcx.lower_to_hir(id.def_id).as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs); providers.opt_ast_lowering_delayed_lints = - |tcx, id| tcx.hir_crate(()).owner(tcx, id.def_id).as_owner().map(|o| &o.delayed_lints); + |tcx, id| tcx.lower_to_hir(id.def_id).as_owner().map(|o| &o.delayed_lints); providers.def_span = |tcx, def_id| tcx.hir_span(tcx.local_def_id_to_hir_id(def_id)); providers.def_ident_span = |tcx, def_id| { let hir_id = tcx.local_def_id_to_hir_id(def_id); @@ -508,7 +440,6 @@ pub fn provide(providers: &mut Providers) { |tcx, trait_id| tcx.resolutions(()).trait_impls.get(&trait_id).map_or(&[], |xs| &xs[..]); providers.expn_that_defined = |tcx, id| tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root()); - providers.in_scope_traits_map = |tcx, id| { - tcx.hir_crate(()).owner(tcx, id.def_id).as_owner().map(|owner_info| &owner_info.trait_map) - }; + providers.in_scope_traits_map = + |tcx, id| tcx.lower_to_hir(id.def_id).as_owner().map(|owner_info| &owner_info.trait_map); } diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index 7c6ab642b2736..05d030b4745af 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -82,7 +82,6 @@ use rustc_span::def_id::LOCAL_CRATE; use rustc_span::{DUMMY_SP, LocalExpnId, Span, Spanned, Symbol}; use rustc_target::spec::PanicStrategy; -use crate::hir::Crate; use crate::infer::canonical::{self, Canonical}; use crate::lint::LintExpectation; use crate::metadata::ModChild; @@ -181,12 +180,26 @@ rustc_queries! { desc { "getting the resolver outputs" } } - query resolver_for_lowering_raw(_: ()) -> (&'tcx Steal<(ty::ResolverAstLowering<'tcx>, Arc)>, &'tcx ty::ResolverGlobalCtxt) { + query resolver_for_lowering_raw(_: ()) -> ( + &'tcx Steal>, + &'tcx Steal, + &'tcx ty::ResolverGlobalCtxt, + ) { eval_always no_hash desc { "getting the resolver for lowering" } } + query index_ast(_: ()) -> &'tcx IndexVec>, + ast::AstOwner, + )>> { + arena_cache + eval_always + no_hash + desc { "getting the AST for lowering" } + } + /// Return the span for a definition. /// /// Contrary to `def_span` below, this query returns the full absolute span of the definition. @@ -198,27 +211,9 @@ rustc_queries! { desc { "getting the source span" } } - /// Represents crate as a whole (as distinct from the top-level crate module). - /// - /// If you call `tcx.hir_crate(())` we will have to assume that any change - /// means that you need to be recompiled. This is because the `hir_crate` - /// query gives you access to all other items. To avoid this fate, do not - /// call `tcx.hir_crate(())`; instead, prefer wrappers like - /// [`TyCtxt::hir_visit_all_item_likes_in_crate`]. - query hir_crate(key: ()) -> &'tcx Crate<'tcx> { - arena_cache - eval_always - desc { "getting the crate HIR" } - } - - query lower_delayed_owner(def_id: LocalDefId) { + query lower_to_hir(key: LocalDefId) -> hir::MaybeOwner<'tcx> { eval_always - desc { "lowering the delayed AST owner `{}`", tcx.def_path_str(def_id) } - } - - query delayed_owner(def_id: LocalDefId) -> hir::MaybeOwner<'tcx> { - feedable - desc { "getting child of lowered delayed AST owner `{}`", tcx.def_path_str(def_id) } + desc { "lower HIR for `{}`", tcx.def_path_str(key.to_def_id()) } } /// All items in the crate. diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index a6ff238ad6f0b..125cf50c6f926 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -147,6 +147,10 @@ impl Erasable for (&'_ T0, &'_ T1) { type Storage = [u8; size_of::<(&'_ (), &'_ ())>()]; } +impl Erasable for (&'_ T0, &'_ T1, &'_ T2) { + type Storage = [u8; size_of::<(&'_ (), &'_ (), &'_ ())>()]; +} + macro_rules! impl_erasable_for_types_with_no_type_params { ($($ty:ty),+ $(,)?) => { $( diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index d1f82af3416b6..89d5f00c1bce6 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -36,7 +36,7 @@ use rustc_hir::definitions::{DefPathData, Definitions, PerParentDisambiguatorSta use rustc_hir::intravisit::VisitorExt; use rustc_hir::lang_items::LangItem; use rustc_hir::limit::Limit; -use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, MaybeOwner, Node, TraitCandidate, find_attr}; +use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, Node, TraitCandidate, find_attr}; use rustc_index::IndexVec; use rustc_macros::Diagnostic; use rustc_session::Session; @@ -698,12 +698,6 @@ impl<'tcx> TyCtxt<'tcx> { TyCtxtFeed { tcx: self, key }.type_of(value) } - /// Feeds the HIR delayed owner during AST -> HIR delayed lowering. - pub fn feed_delayed_owner(self, key: LocalDefId, owner: MaybeOwner<'tcx>) { - self.dep_graph.assert_ignored(); - TyCtxtFeed { tcx: self, key }.delayed_owner(owner); - } - // Trait impl item visibility is inherited from its trait when not specified // explicitly. In that case we cannot determine it in early resolve, // but instead are feeding it in late resolve, where we don't have access to the @@ -765,11 +759,11 @@ impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> { let bodies = Default::default(); let attrs = hir::AttributeMap::EMPTY; - let rustc_middle::hir::Hashes { opt_hash_including_bodies, .. } = + let rustc_middle::hir::Hashes { bodies_hash, .. } = self.tcx.hash_owner_nodes(node, &bodies, &attrs.map, attrs.define_opaque); let node = node.into(); self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes { - opt_hash_including_bodies, + opt_hash: bodies_hash, nodes: IndexVec::from_elem_n( hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node }, 1, @@ -2839,8 +2833,9 @@ impl<'tcx> TyCtxt<'tcx> { pub fn resolver_for_lowering( self, - ) -> &'tcx Steal<(ty::ResolverAstLowering<'tcx>, Arc)> { - self.resolver_for_lowering_raw(()).0 + ) -> (&'tcx Steal>, &'tcx Steal) { + let (resolver, krate, _) = self.resolver_for_lowering_raw(()); + (resolver, krate) } pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode { diff --git a/compiler/rustc_mir_transform/src/coverage/hir_info.rs b/compiler/rustc_mir_transform/src/coverage/hir_info.rs index 28fdc52b06cb9..b217c33734068 100644 --- a/compiler/rustc_mir_transform/src/coverage/hir_info.rs +++ b/compiler/rustc_mir_transform/src/coverage/hir_info.rs @@ -69,7 +69,7 @@ pub(crate) fn extract_hir_info<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> E fn hash_mir_source<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &'tcx hir::Body<'tcx>) -> u64 { let owner = hir_body.id().hir_id.owner; tcx.hir_owner_nodes(owner) - .opt_hash_including_bodies + .opt_hash .expect("hash should be present when coverage instrumentation is enabled") .to_smaller_hash() .as_u64() diff --git a/compiler/rustc_passes/src/debugger_visualizer.rs b/compiler/rustc_passes/src/debugger_visualizer.rs index 1f27384d4e7ca..3a7b68692ee37 100644 --- a/compiler/rustc_passes/src/debugger_visualizer.rs +++ b/compiler/rustc_passes/src/debugger_visualizer.rs @@ -68,11 +68,10 @@ impl<'ast> rustc_ast::visit::Visitor<'ast> for DebuggerVisualizerCollector<'_> { /// Traverses and collects the debugger visualizers for a specific crate. fn debugger_visualizers(tcx: TyCtxt<'_>, _: LocalCrate) -> Vec { - let resolver_and_krate = tcx.resolver_for_lowering().borrow(); - let krate = &*resolver_and_krate.1; + let krate = &tcx.resolver_for_lowering().1; let mut visitor = DebuggerVisualizerCollector { sess: tcx.sess, visualizers: Vec::new() }; - rustc_ast::visit::Visitor::visit_crate(&mut visitor, krate); + rustc_ast::visit::Visitor::visit_crate(&mut visitor, &*krate.borrow()); // We are collecting visualizers in AST-order, which is deterministic, // so we don't need to do any explicit sorting in order to get a diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs index b6fb9937dfa45..4b9f894e09a2c 100644 --- a/compiler/rustc_passes/src/lang_items.rs +++ b/compiler/rustc_passes/src/lang_items.rs @@ -246,8 +246,9 @@ impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> { /// Traverses and collects all the lang items in all crates. fn get_lang_items(tcx: TyCtxt<'_>, (): ()) -> LanguageItems { - let resolver = tcx.resolver_for_lowering().borrow(); - let (resolver, krate) = &*resolver; + let (resolver, krate) = tcx.resolver_for_lowering(); + let resolver = &*resolver.borrow(); + let krate = &*krate.borrow(); // Initialize the collector. let mut collector = LanguageItemCollector::new(tcx, resolver); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 21ce508d8560c..6743bb001a84c 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -338,7 +338,7 @@ pub(crate) fn run_global_ctxt( let expanded_macros = { // We need for these variables to be removed to ensure that the `Crate` won't be "stolen" // anymore. - let (_resolver, krate) = &*tcx.resolver_for_lowering().borrow(); + let krate = &*tcx.resolver_for_lowering().1.borrow(); source_macro_expansion(&krate, &render_options, output_format, tcx.sess.source_map()) }; diff --git a/tests/ui/const-generics/invalid-rustc_legacy_const_generics-issue-123077.stderr b/tests/ui/const-generics/invalid-rustc_legacy_const_generics-issue-123077.stderr index 6f5d719006d8f..111d6d524e5fb 100644 --- a/tests/ui/const-generics/invalid-rustc_legacy_const_generics-issue-123077.stderr +++ b/tests/ui/const-generics/invalid-rustc_legacy_const_generics-issue-123077.stderr @@ -67,9 +67,10 @@ LL | struct F(); help: try using a const generic argument instead | LL ~ std::arch::x86_64::_mm_blend_ps::<{ { -LL + struct F(); -LL + 1 -LL ~ } }>(loop {}, loop {}); +LL + struct F(); +LL + +LL + 1 +LL ~ } }>(loop {}, loop {}); | error: invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items diff --git a/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.stderr b/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.stderr index d81b7d142c92f..d529d9c0f2b21 100644 --- a/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.stderr +++ b/tests/ui/parallel-rustc/default-trait-shadow-cycle-issue-151358.stderr @@ -1,7 +1,7 @@ error: internal compiler error: query cycle when printing cycle detected | = note: ...when getting HIR ID of `Default` - = note: ...which requires getting the crate HIR... + = note: ...which requires lower HIR for `Default`... = note: ...which requires perform lints prior to AST lowering... = note: ...which requires looking up span for `Default`... = note: ...which again requires getting HIR ID of `Default`, completing the cycle @@ -11,7 +11,7 @@ error: internal compiler error: query cycle when printing cycle detected error[E0391]: cycle detected when getting the resolver for lowering | = note: ...which requires getting HIR ID of `Default`... - = note: ...which requires getting the crate HIR... + = note: ...which requires lower HIR for `Default`... = note: ...which requires perform lints prior to AST lowering... = note: ...which again requires getting the resolver for lowering, completing the cycle = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information diff --git a/tests/ui/pin-ergonomics/pin_v2-attr.stderr b/tests/ui/pin-ergonomics/pin_v2-attr.stderr index 5c8a455114c42..8f8a9f3b3a19a 100644 --- a/tests/ui/pin-ergonomics/pin_v2-attr.stderr +++ b/tests/ui/pin-ergonomics/pin_v2-attr.stderr @@ -116,6 +116,14 @@ LL | #[pin_v2] | = help: `#[pin_v2]` can only be applied to data types +error: `#[pin_v2]` attribute cannot be used on delegations + --> $DIR/pin_v2-attr.rs:58:5 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can only be applied to data types + error: `#[pin_v2]` attribute cannot be used on inherent methods --> $DIR/pin_v2-attr.rs:61:5 | @@ -300,13 +308,5 @@ LL | #[pin_v2] | = help: `#[pin_v2]` can only be applied to data types -error: `#[pin_v2]` attribute cannot be used on delegations - --> $DIR/pin_v2-attr.rs:58:5 - | -LL | #[pin_v2] - | ^^^^^^^^^ - | - = help: `#[pin_v2]` can only be applied to data types - error: aborting due to 39 previous errors diff --git a/tests/ui/query-system/query-cycle-printing-issue-151358.stderr b/tests/ui/query-system/query-cycle-printing-issue-151358.stderr index d81b7d142c92f..d529d9c0f2b21 100644 --- a/tests/ui/query-system/query-cycle-printing-issue-151358.stderr +++ b/tests/ui/query-system/query-cycle-printing-issue-151358.stderr @@ -1,7 +1,7 @@ error: internal compiler error: query cycle when printing cycle detected | = note: ...when getting HIR ID of `Default` - = note: ...which requires getting the crate HIR... + = note: ...which requires lower HIR for `Default`... = note: ...which requires perform lints prior to AST lowering... = note: ...which requires looking up span for `Default`... = note: ...which again requires getting HIR ID of `Default`, completing the cycle @@ -11,7 +11,7 @@ error: internal compiler error: query cycle when printing cycle detected error[E0391]: cycle detected when getting the resolver for lowering | = note: ...which requires getting HIR ID of `Default`... - = note: ...which requires getting the crate HIR... + = note: ...which requires lower HIR for `Default`... = note: ...which requires perform lints prior to AST lowering... = note: ...which again requires getting the resolver for lowering, completing the cycle = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information diff --git a/tests/ui/resolve/query-cycle-issue-124901.stderr b/tests/ui/resolve/query-cycle-issue-124901.stderr index d81b7d142c92f..d529d9c0f2b21 100644 --- a/tests/ui/resolve/query-cycle-issue-124901.stderr +++ b/tests/ui/resolve/query-cycle-issue-124901.stderr @@ -1,7 +1,7 @@ error: internal compiler error: query cycle when printing cycle detected | = note: ...when getting HIR ID of `Default` - = note: ...which requires getting the crate HIR... + = note: ...which requires lower HIR for `Default`... = note: ...which requires perform lints prior to AST lowering... = note: ...which requires looking up span for `Default`... = note: ...which again requires getting HIR ID of `Default`, completing the cycle @@ -11,7 +11,7 @@ error: internal compiler error: query cycle when printing cycle detected error[E0391]: cycle detected when getting the resolver for lowering | = note: ...which requires getting HIR ID of `Default`... - = note: ...which requires getting the crate HIR... + = note: ...which requires lower HIR for `Default`... = note: ...which requires perform lints prior to AST lowering... = note: ...which again requires getting the resolver for lowering, completing the cycle = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information