Store lowering outputs per owner.
This commit is contained in:
parent
f9e1de979d
commit
48a339ddbb
13 changed files with 170 additions and 125 deletions
|
@ -4088,6 +4088,7 @@ dependencies = [
|
||||||
"polonius-engine",
|
"polonius-engine",
|
||||||
"rand 0.8.4",
|
"rand 0.8.4",
|
||||||
"rand_xoshiro 0.6.0",
|
"rand_xoshiro 0.6.0",
|
||||||
|
"rustc-rayon",
|
||||||
"rustc-rayon-core",
|
"rustc-rayon-core",
|
||||||
"rustc_apfloat",
|
"rustc_apfloat",
|
||||||
"rustc_arena",
|
"rustc_arena",
|
||||||
|
|
|
@ -252,9 +252,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
}
|
}
|
||||||
// Merge attributes into the inner expression.
|
// Merge attributes into the inner expression.
|
||||||
if !e.attrs.is_empty() {
|
if !e.attrs.is_empty() {
|
||||||
let old_attrs = self.attrs.get(&ex.hir_id).map(|la| *la).unwrap_or(&[]);
|
let old_attrs =
|
||||||
|
self.attrs.get(&ex.hir_id.local_id).map(|la| *la).unwrap_or(&[]);
|
||||||
self.attrs.insert(
|
self.attrs.insert(
|
||||||
ex.hir_id,
|
ex.hir_id.local_id,
|
||||||
&*self.arena.alloc_from_iter(
|
&*self.arena.alloc_from_iter(
|
||||||
e.attrs
|
e.attrs
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
@ -10,6 +10,7 @@ use rustc_errors::struct_span_err;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
|
use rustc_index::vec::Idx;
|
||||||
use rustc_span::source_map::{respan, DesugaringKind};
|
use rustc_span::source_map::{respan, DesugaringKind};
|
||||||
use rustc_span::symbol::{kw, sym, Ident};
|
use rustc_span::symbol::{kw, sym, Ident};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -99,11 +100,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
) -> T {
|
) -> T {
|
||||||
let old_len = self.in_scope_lifetimes.len();
|
let old_len = self.in_scope_lifetimes.len();
|
||||||
|
|
||||||
let parent_generics = match self.owners[parent_hir_id].unwrap().expect_item().kind {
|
let parent_generics =
|
||||||
hir::ItemKind::Impl(hir::Impl { ref generics, .. })
|
match self.owners[parent_hir_id].as_ref().unwrap().node.expect_item().kind {
|
||||||
| hir::ItemKind::Trait(_, _, ref generics, ..) => generics.params,
|
hir::ItemKind::Impl(hir::Impl { ref generics, .. })
|
||||||
_ => &[],
|
| hir::ItemKind::Trait(_, _, ref generics, ..) => generics.params,
|
||||||
};
|
_ => &[],
|
||||||
|
};
|
||||||
let lt_def_names = parent_generics.iter().filter_map(|param| match param.kind {
|
let lt_def_names = parent_generics.iter().filter_map(|param| match param.kind {
|
||||||
hir::GenericParamKind::Lifetime { .. } => Some(param.name.normalize_to_macros_2_0()),
|
hir::GenericParamKind::Lifetime { .. } => Some(param.name.normalize_to_macros_2_0()),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -493,7 +495,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
let kind = hir::ItemKind::Use(path, hir::UseKind::Single);
|
let kind = hir::ItemKind::Use(path, hir::UseKind::Single);
|
||||||
let vis = this.rebuild_vis(&vis);
|
let vis = this.rebuild_vis(&vis);
|
||||||
if let Some(attrs) = attrs {
|
if let Some(attrs) = attrs {
|
||||||
this.attrs.insert(hir::HirId::make_owner(new_id), attrs);
|
this.attrs.insert(hir::ItemLocalId::new(0), attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
let item = hir::Item {
|
let item = hir::Item {
|
||||||
|
@ -568,7 +570,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
let kind =
|
let kind =
|
||||||
this.lower_use_tree(use_tree, &prefix, id, &mut vis, &mut ident, attrs);
|
this.lower_use_tree(use_tree, &prefix, id, &mut vis, &mut ident, attrs);
|
||||||
if let Some(attrs) = attrs {
|
if let Some(attrs) = attrs {
|
||||||
this.attrs.insert(hir::HirId::make_owner(new_hir_id), attrs);
|
this.attrs.insert(hir::ItemLocalId::new(0), attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
let item = hir::Item {
|
let item = hir::Item {
|
||||||
|
@ -971,7 +973,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
) -> hir::BodyId {
|
) -> hir::BodyId {
|
||||||
let body = hir::Body { generator_kind: self.generator_kind, params, value };
|
let body = hir::Body { generator_kind: self.generator_kind, params, value };
|
||||||
let id = body.id();
|
let id = body.id();
|
||||||
self.bodies.insert(id, body);
|
debug_assert_eq!(id.hir_id.owner, self.current_hir_id_owner);
|
||||||
|
self.bodies.insert(id.hir_id.local_id, body);
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1124,7 +1127,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
//
|
//
|
||||||
// If this is the simple case, this parameter will end up being the same as the
|
// If this is the simple case, this parameter will end up being the same as the
|
||||||
// original parameter, but with a different pattern id.
|
// original parameter, but with a different pattern id.
|
||||||
let stmt_attrs = this.attrs.get(¶meter.hir_id).copied();
|
let stmt_attrs = this.attrs.get(¶meter.hir_id.local_id).copied();
|
||||||
let (new_parameter_pat, new_parameter_id) = this.pat_ident(desugared_span, ident);
|
let (new_parameter_pat, new_parameter_id) = this.pat_ident(desugared_span, ident);
|
||||||
let new_parameter = hir::Param {
|
let new_parameter = hir::Param {
|
||||||
hir_id: parameter.hir_id,
|
hir_id: parameter.hir_id,
|
||||||
|
|
|
@ -35,14 +35,13 @@
|
||||||
#![feature(iter_zip)]
|
#![feature(iter_zip)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
use rustc_ast::node_id::NodeMap;
|
|
||||||
use rustc_ast::token::{self, Token};
|
use rustc_ast::token::{self, Token};
|
||||||
use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream, TokenTree};
|
use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream, TokenTree};
|
||||||
use rustc_ast::visit;
|
use rustc_ast::visit;
|
||||||
use rustc_ast::{self as ast, *};
|
use rustc_ast::{self as ast, *};
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_data_structures::captures::Captures;
|
use rustc_data_structures::captures::Captures;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_errors::{struct_span_err, Applicability};
|
use rustc_errors::{struct_span_err, Applicability};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
@ -97,13 +96,12 @@ struct LoweringContext<'a, 'hir: 'a> {
|
||||||
arena: &'hir Arena<'hir>,
|
arena: &'hir Arena<'hir>,
|
||||||
|
|
||||||
/// The items being lowered are collected here.
|
/// The items being lowered are collected here.
|
||||||
owners: IndexVec<LocalDefId, Option<hir::OwnerNode<'hir>>>,
|
owners: IndexVec<LocalDefId, Option<hir::OwnerInfo<'hir>>>,
|
||||||
bodies: BTreeMap<hir::BodyId, hir::Body<'hir>>,
|
bodies: BTreeMap<hir::ItemLocalId, hir::Body<'hir>>,
|
||||||
|
attrs: BTreeMap<hir::ItemLocalId, &'hir [Attribute]>,
|
||||||
|
|
||||||
generator_kind: Option<hir::GeneratorKind>,
|
generator_kind: Option<hir::GeneratorKind>,
|
||||||
|
|
||||||
attrs: BTreeMap<hir::HirId, &'hir [Attribute]>,
|
|
||||||
|
|
||||||
/// When inside an `async` context, this is the `HirId` of the
|
/// When inside an `async` context, this is the `HirId` of the
|
||||||
/// `task_context` local bound to the resume argument of the generator.
|
/// `task_context` local bound to the resume argument of the generator.
|
||||||
task_context: Option<hir::HirId>,
|
task_context: Option<hir::HirId>,
|
||||||
|
@ -152,6 +150,9 @@ struct LoweringContext<'a, 'hir: 'a> {
|
||||||
item_local_id_counter: hir::ItemLocalId,
|
item_local_id_counter: hir::ItemLocalId,
|
||||||
node_id_to_hir_id: IndexVec<NodeId, Option<hir::HirId>>,
|
node_id_to_hir_id: IndexVec<NodeId, Option<hir::HirId>>,
|
||||||
|
|
||||||
|
/// NodeIds that are lowered inside the current HIR owner.
|
||||||
|
local_node_ids: Vec<NodeId>,
|
||||||
|
|
||||||
allow_try_trait: Option<Lrc<[Symbol]>>,
|
allow_try_trait: Option<Lrc<[Symbol]>>,
|
||||||
allow_gen_future: Option<Lrc<[Symbol]>>,
|
allow_gen_future: Option<Lrc<[Symbol]>>,
|
||||||
}
|
}
|
||||||
|
@ -182,7 +183,7 @@ pub trait ResolverAstLowering {
|
||||||
|
|
||||||
fn next_node_id(&mut self) -> NodeId;
|
fn next_node_id(&mut self) -> NodeId;
|
||||||
|
|
||||||
fn take_trait_map(&mut self) -> NodeMap<Vec<hir::TraitCandidate>>;
|
fn take_trait_map(&mut self, node: NodeId) -> Option<Vec<hir::TraitCandidate>>;
|
||||||
|
|
||||||
fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId>;
|
fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId>;
|
||||||
|
|
||||||
|
@ -314,12 +315,13 @@ pub fn lower_crate<'a, 'hir>(
|
||||||
) -> &'hir hir::Crate<'hir> {
|
) -> &'hir hir::Crate<'hir> {
|
||||||
let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering");
|
let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering");
|
||||||
|
|
||||||
|
let owners = IndexVec::from_fn_n(|_| None, resolver.definitions().def_index_count());
|
||||||
LoweringContext {
|
LoweringContext {
|
||||||
sess,
|
sess,
|
||||||
resolver,
|
resolver,
|
||||||
nt_to_tokenstream,
|
nt_to_tokenstream,
|
||||||
arena,
|
arena,
|
||||||
owners: IndexVec::default(),
|
owners,
|
||||||
bodies: BTreeMap::new(),
|
bodies: BTreeMap::new(),
|
||||||
attrs: BTreeMap::default(),
|
attrs: BTreeMap::default(),
|
||||||
catch_scope: None,
|
catch_scope: None,
|
||||||
|
@ -331,6 +333,7 @@ pub fn lower_crate<'a, 'hir>(
|
||||||
current_hir_id_owner: CRATE_DEF_ID,
|
current_hir_id_owner: CRATE_DEF_ID,
|
||||||
item_local_id_counter: hir::ItemLocalId::new(0),
|
item_local_id_counter: hir::ItemLocalId::new(0),
|
||||||
node_id_to_hir_id: IndexVec::new(),
|
node_id_to_hir_id: IndexVec::new(),
|
||||||
|
local_node_ids: Vec::new(),
|
||||||
generator_kind: None,
|
generator_kind: None,
|
||||||
task_context: None,
|
task_context: None,
|
||||||
current_item: None,
|
current_item: None,
|
||||||
|
@ -420,14 +423,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
hir::OwnerNode::Crate(lctx.arena.alloc(module))
|
hir::OwnerNode::Crate(lctx.arena.alloc(module))
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut trait_map: FxHashMap<_, FxHashMap<_, _>> = FxHashMap::default();
|
|
||||||
for (k, v) in self.resolver.take_trait_map().into_iter() {
|
|
||||||
if let Some(Some(hir_id)) = self.node_id_to_hir_id.get(k) {
|
|
||||||
let map = trait_map.entry(hir_id.owner).or_default();
|
|
||||||
map.insert(hir_id.local_id, v.into_boxed_slice());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut def_id_to_hir_id = IndexVec::default();
|
let mut def_id_to_hir_id = IndexVec::default();
|
||||||
|
|
||||||
for (node_id, hir_id) in self.node_id_to_hir_id.into_iter_enumerated() {
|
for (node_id, hir_id) in self.node_id_to_hir_id.into_iter_enumerated() {
|
||||||
|
@ -441,16 +436,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
|
|
||||||
self.resolver.definitions().init_def_id_to_hir_id_mapping(def_id_to_hir_id);
|
self.resolver.definitions().init_def_id_to_hir_id_mapping(def_id_to_hir_id);
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
let krate = hir::Crate { owners: self.owners };
|
||||||
for (&id, attrs) in self.attrs.iter() {
|
|
||||||
// Verify that we do not store empty slices in the map.
|
|
||||||
if attrs.is_empty() {
|
|
||||||
panic!("Stored empty attributes for {:?}", id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let krate =
|
|
||||||
hir::Crate { owners: self.owners, bodies: self.bodies, trait_map, attrs: self.attrs };
|
|
||||||
self.arena.alloc(krate)
|
self.arena.alloc(krate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,25 +454,57 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
) -> LocalDefId {
|
) -> LocalDefId {
|
||||||
let def_id = self.resolver.local_def_id(owner);
|
let def_id = self.resolver.local_def_id(owner);
|
||||||
|
|
||||||
// Always allocate the first `HirId` for the owner itself.
|
let current_attrs = std::mem::take(&mut self.attrs);
|
||||||
let _old = self.node_id_to_hir_id.insert(owner, hir::HirId::make_owner(def_id));
|
let current_bodies = std::mem::take(&mut self.bodies);
|
||||||
debug_assert_eq!(_old, None);
|
let current_node_ids = std::mem::take(&mut self.local_node_ids);
|
||||||
|
|
||||||
let current_owner = std::mem::replace(&mut self.current_hir_id_owner, def_id);
|
let current_owner = std::mem::replace(&mut self.current_hir_id_owner, def_id);
|
||||||
let current_local_counter =
|
let current_local_counter =
|
||||||
std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1));
|
std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1));
|
||||||
|
|
||||||
let item = f(self);
|
// Always allocate the first `HirId` for the owner itself.
|
||||||
|
let _old = self.node_id_to_hir_id.insert(owner, hir::HirId::make_owner(def_id));
|
||||||
|
debug_assert_eq!(_old, None);
|
||||||
|
self.local_node_ids.push(owner);
|
||||||
|
|
||||||
|
let item = f(self);
|
||||||
|
let info = self.make_owner_info(item);
|
||||||
|
|
||||||
|
self.attrs = current_attrs;
|
||||||
|
self.bodies = current_bodies;
|
||||||
|
self.local_node_ids = current_node_ids;
|
||||||
self.current_hir_id_owner = current_owner;
|
self.current_hir_id_owner = current_owner;
|
||||||
self.item_local_id_counter = current_local_counter;
|
self.item_local_id_counter = current_local_counter;
|
||||||
|
|
||||||
let _old = self.owners.insert(def_id, item);
|
let _old = self.owners.insert(def_id, info);
|
||||||
debug_assert!(_old.is_none());
|
debug_assert!(_old.is_none());
|
||||||
|
|
||||||
def_id
|
def_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> hir::OwnerInfo<'hir> {
|
||||||
|
let attrs = std::mem::take(&mut self.attrs);
|
||||||
|
let bodies = std::mem::take(&mut self.bodies);
|
||||||
|
let local_node_ids = std::mem::take(&mut self.local_node_ids);
|
||||||
|
let trait_map = local_node_ids
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|node_id| {
|
||||||
|
let hir_id = self.node_id_to_hir_id[node_id]?;
|
||||||
|
let traits = self.resolver.take_trait_map(node_id)?;
|
||||||
|
Some((hir_id.local_id, traits.into_boxed_slice()))
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
for (&id, attrs) in attrs.iter() {
|
||||||
|
// Verify that we do not store empty slices in the map.
|
||||||
|
if attrs.is_empty() {
|
||||||
|
panic!("Stored empty attributes for {:?}", id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hir::OwnerInfo { node, attrs, bodies, trait_map }
|
||||||
|
}
|
||||||
|
|
||||||
/// This method allocates a new `HirId` for the given `NodeId` and stores it in
|
/// This method allocates a new `HirId` for the given `NodeId` and stores it in
|
||||||
/// the `LoweringContext`'s `NodeId => HirId` map.
|
/// the `LoweringContext`'s `NodeId => HirId` map.
|
||||||
/// Take care not to call this method if the resulting `HirId` is then not
|
/// Take care not to call this method if the resulting `HirId` is then not
|
||||||
|
@ -501,6 +519,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
let owner = self.current_hir_id_owner;
|
let owner = self.current_hir_id_owner;
|
||||||
let local_id = self.item_local_id_counter;
|
let local_id = self.item_local_id_counter;
|
||||||
self.item_local_id_counter.increment_by(1);
|
self.item_local_id_counter.increment_by(1);
|
||||||
|
self.local_node_ids.push(ast_node_id);
|
||||||
hir::HirId { owner, local_id }
|
hir::HirId { owner, local_id }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -791,9 +810,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
if attrs.is_empty() {
|
if attrs.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
debug_assert_eq!(id.owner, self.current_hir_id_owner);
|
||||||
let ret = self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a)));
|
let ret = self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a)));
|
||||||
debug_assert!(!ret.is_empty());
|
debug_assert!(!ret.is_empty());
|
||||||
self.attrs.insert(id, ret);
|
self.attrs.insert(id.local_id, ret);
|
||||||
Some(ret)
|
Some(ret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -819,9 +839,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alias_attrs(&mut self, id: hir::HirId, target_id: hir::HirId) {
|
fn alias_attrs(&mut self, id: hir::HirId, target_id: hir::HirId) {
|
||||||
if let Some(&a) = self.attrs.get(&target_id) {
|
debug_assert_eq!(id.owner, self.current_hir_id_owner);
|
||||||
|
debug_assert_eq!(target_id.owner, self.current_hir_id_owner);
|
||||||
|
if let Some(&a) = self.attrs.get(&target_id.local_id) {
|
||||||
debug_assert!(!a.is_empty());
|
debug_assert!(!a.is_empty());
|
||||||
self.attrs.insert(id, a);
|
self.attrs.insert(id.local_id, a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2066,7 +2088,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
let hir_id = self.next_id();
|
let hir_id = self.next_id();
|
||||||
if let Some(a) = attrs {
|
if let Some(a) = attrs {
|
||||||
debug_assert!(!a.is_empty());
|
debug_assert!(!a.is_empty());
|
||||||
self.attrs.insert(hir_id, a);
|
self.attrs.insert(hir_id.local_id, a);
|
||||||
}
|
}
|
||||||
let local = hir::Local { hir_id, init, pat, source, span: self.lower_span(span), ty: None };
|
let local = hir::Local { hir_id, init, pat, source, span: self.lower_span(span), ty: None };
|
||||||
self.stmt(span, hir::StmtKind::Local(self.arena.alloc(local)))
|
self.stmt(span, hir::StmtKind::Local(self.arena.alloc(local)))
|
||||||
|
|
|
@ -662,6 +662,16 @@ pub struct WhereEqPredicate<'hir> {
|
||||||
pub rhs_ty: &'hir Ty<'hir>,
|
pub rhs_ty: &'hir Ty<'hir>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct OwnerInfo<'hir> {
|
||||||
|
pub node: OwnerNode<'hir>,
|
||||||
|
pub attrs: BTreeMap<ItemLocalId, &'hir [Attribute]>,
|
||||||
|
pub bodies: BTreeMap<ItemLocalId, Body<'hir>>,
|
||||||
|
/// Map indicating what traits are in scope for places where this
|
||||||
|
/// is relevant; generated by resolve.
|
||||||
|
pub trait_map: FxHashMap<ItemLocalId, Box<[TraitCandidate]>>,
|
||||||
|
}
|
||||||
|
|
||||||
/// The top-level data structure that stores the entire contents of
|
/// The top-level data structure that stores the entire contents of
|
||||||
/// the crate currently being compiled.
|
/// the crate currently being compiled.
|
||||||
///
|
///
|
||||||
|
@ -670,40 +680,39 @@ pub struct WhereEqPredicate<'hir> {
|
||||||
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html
|
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Crate<'hir> {
|
pub struct Crate<'hir> {
|
||||||
pub owners: IndexVec<LocalDefId, Option<OwnerNode<'hir>>>,
|
pub owners: IndexVec<LocalDefId, Option<OwnerInfo<'hir>>>,
|
||||||
pub bodies: BTreeMap<BodyId, Body<'hir>>,
|
|
||||||
|
|
||||||
/// Map indicating what traits are in scope for places where this
|
|
||||||
/// is relevant; generated by resolve.
|
|
||||||
pub trait_map: FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Box<[TraitCandidate]>>>,
|
|
||||||
|
|
||||||
/// Collected attributes from HIR nodes.
|
|
||||||
pub attrs: BTreeMap<HirId, &'hir [Attribute]>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Crate<'hir> {
|
impl Crate<'hir> {
|
||||||
pub fn module(&self) -> &'hir Mod<'hir> {
|
pub fn module(&self) -> &'hir Mod<'hir> {
|
||||||
if let Some(OwnerNode::Crate(m)) = self.owners[CRATE_DEF_ID] { m } else { panic!() }
|
let i = self.owners[CRATE_DEF_ID].as_ref().unwrap().node;
|
||||||
|
if let OwnerNode::Crate(m) = i { m } else { panic!() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn item(&self, id: ItemId) -> &'hir Item<'hir> {
|
pub fn item(&self, id: ItemId) -> &'hir Item<'hir> {
|
||||||
self.owners[id.def_id].as_ref().unwrap().expect_item()
|
self.owners[id.def_id].as_ref().unwrap().node.expect_item()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir> {
|
pub fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir> {
|
||||||
self.owners[id.def_id].as_ref().unwrap().expect_trait_item()
|
self.owners[id.def_id].as_ref().unwrap().node.expect_trait_item()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir> {
|
pub fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir> {
|
||||||
self.owners[id.def_id].as_ref().unwrap().expect_impl_item()
|
self.owners[id.def_id].as_ref().unwrap().node.expect_impl_item()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir> {
|
pub fn foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir> {
|
||||||
self.owners[id.def_id].as_ref().unwrap().expect_foreign_item()
|
self.owners[id.def_id].as_ref().unwrap().node.expect_foreign_item()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn body(&self, id: BodyId) -> &Body<'hir> {
|
pub fn body(&self, id: BodyId) -> &Body<'hir> {
|
||||||
&self.bodies[&id]
|
let HirId { owner, local_id } = id.hir_id;
|
||||||
|
&self.owners[owner].as_ref().unwrap().bodies[&local_id]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn attrs(&self, id: HirId) -> &'hir [Attribute] {
|
||||||
|
let HirId { owner, local_id } = id;
|
||||||
|
&self.owners[owner].as_ref().unwrap().attrs.get(&local_id).map(|la| *la).unwrap_or(&[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ bitflags = "1.2.1"
|
||||||
either = "1.5.0"
|
either = "1.5.0"
|
||||||
gsgdt = "0.1.2"
|
gsgdt = "0.1.2"
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
|
rustc-rayon = "0.3.1"
|
||||||
rustc-rayon-core = "0.3.1"
|
rustc-rayon-core = "0.3.1"
|
||||||
polonius-engine = "0.13.0"
|
polonius-engine = "0.13.0"
|
||||||
rustc_apfloat = { path = "../rustc_apfloat" }
|
rustc_apfloat = { path = "../rustc_apfloat" }
|
||||||
|
|
|
@ -86,12 +86,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||||
collector
|
collector
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn finalize_and_compute_crate_hash(mut self) -> IndexedHir<'hir> {
|
pub(super) fn finalize_and_compute_crate_hash(self) -> IndexedHir<'hir> {
|
||||||
// Insert bodies into the map
|
|
||||||
for (id, body) in self.krate.bodies.iter() {
|
|
||||||
let bodies = &mut self.map[id.hir_id.owner].as_mut().unwrap().bodies;
|
|
||||||
assert!(bodies.insert(id.hir_id.local_id, body).is_none());
|
|
||||||
}
|
|
||||||
IndexedHir { map: self.map, parenting: self.parenting }
|
IndexedHir { map: self.map, parenting: self.parenting }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,9 +96,14 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||||
let mut nodes = IndexVec::new();
|
let mut nodes = IndexVec::new();
|
||||||
nodes.push(Some(ParentedNode { parent: ItemLocalId::new(0), node: node.into() }));
|
nodes.push(Some(ParentedNode { parent: ItemLocalId::new(0), node: node.into() }));
|
||||||
|
|
||||||
|
let mut bodies = FxHashMap::default();
|
||||||
|
for (id, body) in self.krate.owners[owner].as_ref().unwrap().bodies.iter() {
|
||||||
|
let _old = bodies.insert(*id, body);
|
||||||
|
debug_assert!(_old.is_none());
|
||||||
|
}
|
||||||
|
|
||||||
debug_assert!(self.map[owner].is_none());
|
debug_assert!(self.map[owner].is_none());
|
||||||
self.map[owner] =
|
self.map[owner] = Some(self.arena.alloc(OwnerNodes { hash, nodes, bodies }));
|
||||||
Some(self.arena.alloc(OwnerNodes { hash, nodes, bodies: FxHashMap::default() }));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert(&mut self, span: Span, hir_id: HirId, node: Node<'hir>) {
|
fn insert(&mut self, span: Span, hir_id: HirId, node: Node<'hir>) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use self::collector::NodeCollector;
|
use self::collector::NodeCollector;
|
||||||
|
|
||||||
use crate::hir::{AttributeMap, IndexedHir, ModuleItems, Owner};
|
use crate::hir::{IndexedHir, ModuleItems, Owner};
|
||||||
use crate::ty::TyCtxt;
|
use crate::ty::TyCtxt;
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_data_structures::fingerprint::Fingerprint;
|
use rustc_data_structures::fingerprint::Fingerprint;
|
||||||
|
@ -166,8 +166,8 @@ impl<'hir> Map<'hir> {
|
||||||
|
|
||||||
pub fn items(&self) -> impl Iterator<Item = &'hir Item<'hir>> + 'hir {
|
pub fn items(&self) -> impl Iterator<Item = &'hir Item<'hir>> + 'hir {
|
||||||
let krate = self.krate();
|
let krate = self.krate();
|
||||||
krate.owners.iter().filter_map(|owner| match owner.as_ref()? {
|
krate.owners.iter().filter_map(|owner| match owner.as_ref()?.node {
|
||||||
OwnerNode::Item(item) => Some(*item),
|
OwnerNode::Item(item) => Some(item),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -495,11 +495,35 @@ impl<'hir> Map<'hir> {
|
||||||
/// crate. If you would prefer to iterate over the bodies
|
/// crate. If you would prefer to iterate over the bodies
|
||||||
/// themselves, you can do `self.hir().krate().body_ids.iter()`.
|
/// themselves, you can do `self.hir().krate().body_ids.iter()`.
|
||||||
pub fn body_owners(self) -> impl Iterator<Item = LocalDefId> + 'hir {
|
pub fn body_owners(self) -> impl Iterator<Item = LocalDefId> + 'hir {
|
||||||
self.krate().bodies.keys().map(move |&body_id| self.body_owner_def_id(body_id))
|
self.krate()
|
||||||
|
.owners
|
||||||
|
.iter_enumerated()
|
||||||
|
.flat_map(move |(owner, owner_info)| {
|
||||||
|
let bodies = &owner_info.as_ref()?.bodies;
|
||||||
|
Some(bodies.keys().map(move |&local_id| {
|
||||||
|
let hir_id = HirId { owner, local_id };
|
||||||
|
let body_id = BodyId { hir_id };
|
||||||
|
self.body_owner_def_id(body_id)
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
.flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn par_body_owners<F: Fn(LocalDefId) + Sync + Send>(self, f: F) {
|
pub fn par_body_owners<F: Fn(LocalDefId) + Sync + Send>(self, f: F) {
|
||||||
par_for_each_in(&self.krate().bodies, |(&body_id, _)| f(self.body_owner_def_id(body_id)));
|
use rustc_data_structures::sync::{par_iter, ParallelIterator};
|
||||||
|
#[cfg(parallel_compiler)]
|
||||||
|
use rustc_rayon::iter::IndexedParallelIterator;
|
||||||
|
|
||||||
|
par_iter(&self.krate().owners.raw).enumerate().for_each(|(owner, owner_info)| {
|
||||||
|
let owner = LocalDefId::new(owner);
|
||||||
|
if let Some(owner_info) = owner_info {
|
||||||
|
par_iter(&owner_info.bodies).for_each(|(&local_id, _)| {
|
||||||
|
let hir_id = HirId { owner, local_id };
|
||||||
|
let body_id = BodyId { hir_id };
|
||||||
|
f(self.body_owner_def_id(body_id))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ty_param_owner(&self, id: HirId) -> HirId {
|
pub fn ty_param_owner(&self, id: HirId) -> HirId {
|
||||||
|
@ -551,9 +575,14 @@ impl<'hir> Map<'hir> {
|
||||||
/// Walks the attributes in a crate.
|
/// Walks the attributes in a crate.
|
||||||
pub fn walk_attributes(self, visitor: &mut impl Visitor<'hir>) {
|
pub fn walk_attributes(self, visitor: &mut impl Visitor<'hir>) {
|
||||||
let krate = self.krate();
|
let krate = self.krate();
|
||||||
for (&id, attrs) in krate.attrs.iter() {
|
for (owner, info) in krate.owners.iter_enumerated() {
|
||||||
for a in *attrs {
|
if let Some(info) = info {
|
||||||
visitor.visit_attribute(id, a)
|
for (&local_id, attrs) in info.attrs.iter() {
|
||||||
|
let id = HirId { owner, local_id };
|
||||||
|
for a in *attrs {
|
||||||
|
visitor.visit_attribute(id, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -572,7 +601,7 @@ impl<'hir> Map<'hir> {
|
||||||
{
|
{
|
||||||
let krate = self.krate();
|
let krate = self.krate();
|
||||||
for owner in krate.owners.iter().filter_map(Option::as_ref) {
|
for owner in krate.owners.iter().filter_map(Option::as_ref) {
|
||||||
match owner {
|
match owner.node {
|
||||||
OwnerNode::Item(item) => visitor.visit_item(item),
|
OwnerNode::Item(item) => visitor.visit_item(item),
|
||||||
OwnerNode::ForeignItem(item) => visitor.visit_foreign_item(item),
|
OwnerNode::ForeignItem(item) => visitor.visit_foreign_item(item),
|
||||||
OwnerNode::ImplItem(item) => visitor.visit_impl_item(item),
|
OwnerNode::ImplItem(item) => visitor.visit_impl_item(item),
|
||||||
|
@ -588,7 +617,7 @@ impl<'hir> Map<'hir> {
|
||||||
V: itemlikevisit::ParItemLikeVisitor<'hir> + Sync + Send,
|
V: itemlikevisit::ParItemLikeVisitor<'hir> + Sync + Send,
|
||||||
{
|
{
|
||||||
let krate = self.krate();
|
let krate = self.krate();
|
||||||
par_for_each_in(&krate.owners.raw, |owner| match owner.as_ref() {
|
par_for_each_in(&krate.owners.raw, |owner| match owner.as_ref().map(|o| o.node) {
|
||||||
Some(OwnerNode::Item(item)) => visitor.visit_item(item),
|
Some(OwnerNode::Item(item)) => visitor.visit_item(item),
|
||||||
Some(OwnerNode::ForeignItem(item)) => visitor.visit_foreign_item(item),
|
Some(OwnerNode::ForeignItem(item)) => visitor.visit_foreign_item(item),
|
||||||
Some(OwnerNode::ImplItem(item)) => visitor.visit_impl_item(item),
|
Some(OwnerNode::ImplItem(item)) => visitor.visit_impl_item(item),
|
||||||
|
@ -1091,7 +1120,10 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
|
||||||
for (def_path_hash, fingerprint, def_id) in hir_body_nodes.iter() {
|
for (def_path_hash, fingerprint, def_id) in hir_body_nodes.iter() {
|
||||||
def_path_hash.0.hash_stable(&mut hcx, &mut stable_hasher);
|
def_path_hash.0.hash_stable(&mut hcx, &mut stable_hasher);
|
||||||
fingerprint.hash_stable(&mut hcx, &mut stable_hasher);
|
fingerprint.hash_stable(&mut hcx, &mut stable_hasher);
|
||||||
AttributeMap { map: &tcx.untracked_crate.attrs, prefix: *def_id }
|
tcx.untracked_crate.owners[*def_id]
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.attrs
|
||||||
.hash_stable(&mut hcx, &mut stable_hasher);
|
.hash_stable(&mut hcx, &mut stable_hasher);
|
||||||
if tcx.sess.opts.debugging_opts.incremental_relative_spans {
|
if tcx.sess.opts.debugging_opts.incremental_relative_spans {
|
||||||
let span = tcx.untracked_resolutions.definitions.def_span(*def_id);
|
let span = tcx.untracked_resolutions.definitions.def_span(*def_id);
|
||||||
|
|
|
@ -77,47 +77,21 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for OwnerNodes<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attributes owner by a HIR owner. It is build as a slice inside the attributes map, restricted
|
/// Attributes owner by a HIR owner.
|
||||||
/// to the nodes whose `HirId::owner` is `prefix`.
|
#[derive(Copy, Clone, Debug, HashStable)]
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct AttributeMap<'tcx> {
|
pub struct AttributeMap<'tcx> {
|
||||||
map: &'tcx BTreeMap<HirId, &'tcx [Attribute]>,
|
map: &'tcx BTreeMap<ItemLocalId, &'tcx [Attribute]>,
|
||||||
prefix: LocalDefId,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for AttributeMap<'tcx> {
|
|
||||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
|
||||||
let range = self.range();
|
|
||||||
|
|
||||||
range.clone().count().hash_stable(hcx, hasher);
|
|
||||||
for (key, value) in range {
|
|
||||||
key.hash_stable(hcx, hasher);
|
|
||||||
value.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> std::fmt::Debug for AttributeMap<'tcx> {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
f.debug_struct("AttributeMap")
|
|
||||||
.field("prefix", &self.prefix)
|
|
||||||
.field("range", &&self.range().collect::<Vec<_>>()[..])
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> AttributeMap<'tcx> {
|
impl<'tcx> AttributeMap<'tcx> {
|
||||||
fn get(&self, id: ItemLocalId) -> &'tcx [Attribute] {
|
fn new(owner_info: &'tcx Option<OwnerInfo<'tcx>>) -> AttributeMap<'tcx> {
|
||||||
self.map.get(&HirId { owner: self.prefix, local_id: id }).copied().unwrap_or(&[])
|
const FALLBACK: &'static BTreeMap<ItemLocalId, &'static [Attribute]> = &BTreeMap::new();
|
||||||
|
let map = owner_info.as_ref().map_or(FALLBACK, |info| &info.attrs);
|
||||||
|
AttributeMap { map }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn range(&self) -> std::collections::btree_map::Range<'_, rustc_hir::HirId, &[Attribute]> {
|
fn get(&self, id: ItemLocalId) -> &'tcx [Attribute] {
|
||||||
let local_zero = ItemLocalId::from_u32(0);
|
self.map.get(&id).copied().unwrap_or(&[])
|
||||||
let range = HirId { owner: self.prefix, local_id: local_zero }..HirId {
|
|
||||||
owner: LocalDefId { local_def_index: self.prefix.local_def_index + 1 },
|
|
||||||
local_id: local_zero,
|
|
||||||
};
|
|
||||||
self.map.range(range)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +137,7 @@ pub fn provide(providers: &mut Providers) {
|
||||||
let index = tcx.index_hir(());
|
let index = tcx.index_hir(());
|
||||||
index.parenting.get(&id).copied().unwrap_or(CRATE_HIR_ID)
|
index.parenting.get(&id).copied().unwrap_or(CRATE_HIR_ID)
|
||||||
};
|
};
|
||||||
providers.hir_attrs = |tcx, id| AttributeMap { map: &tcx.hir_crate(()).attrs, prefix: id };
|
providers.hir_attrs = |tcx, id| AttributeMap::new(&tcx.hir_crate(()).owners[id]);
|
||||||
providers.source_span = |tcx, def_id| tcx.resolutions(()).definitions.def_span(def_id);
|
providers.source_span = |tcx, def_id| tcx.resolutions(()).definitions.def_span(def_id);
|
||||||
providers.def_span = |tcx, def_id| tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP);
|
providers.def_span = |tcx, def_id| tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP);
|
||||||
providers.fn_arg_names = |tcx, id| {
|
providers.fn_arg_names = |tcx, id| {
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#![feature(bool_to_option)]
|
#![feature(bool_to_option)]
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
|
#![feature(const_btree_new)]
|
||||||
#![feature(discriminant_kind)]
|
#![feature(discriminant_kind)]
|
||||||
#![feature(exhaustive_patterns)]
|
#![feature(exhaustive_patterns)]
|
||||||
#![feature(if_let_guard)]
|
#![feature(if_let_guard)]
|
||||||
|
|
|
@ -2828,7 +2828,8 @@ fn ptr_eq<T, U>(t: *const T, u: *const U) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn provide(providers: &mut ty::query::Providers) {
|
pub fn provide(providers: &mut ty::query::Providers) {
|
||||||
providers.in_scope_traits_map = |tcx, id| tcx.hir_crate(()).trait_map.get(&id);
|
providers.in_scope_traits_map =
|
||||||
|
|tcx, id| tcx.hir_crate(()).owners[id].as_ref().map(|owner_info| &owner_info.trait_map);
|
||||||
providers.resolutions = |tcx, ()| &tcx.untracked_resolutions;
|
providers.resolutions = |tcx, ()| &tcx.untracked_resolutions;
|
||||||
providers.module_exports = |tcx, id| tcx.resolutions(()).export_map.get(&id).map(|v| &v[..]);
|
providers.module_exports = |tcx, id| tcx.resolutions(()).export_map.get(&id).map(|v| &v[..]);
|
||||||
providers.crate_name = |tcx, id| {
|
providers.crate_name = |tcx, id| {
|
||||||
|
|
|
@ -1994,7 +1994,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
if ns == ValueNS {
|
if ns == ValueNS {
|
||||||
let item_name = path.last().unwrap().ident;
|
let item_name = path.last().unwrap().ident;
|
||||||
let traits = self.traits_in_scope(item_name, ns);
|
let traits = self.traits_in_scope(item_name, ns);
|
||||||
self.r.trait_map.as_mut().unwrap().insert(id, traits);
|
self.r.trait_map.insert(id, traits);
|
||||||
}
|
}
|
||||||
|
|
||||||
if PrimTy::from_name(path[0].ident.name).is_some() {
|
if PrimTy::from_name(path[0].ident.name).is_some() {
|
||||||
|
@ -2479,12 +2479,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
// the field name so that we can do some nice error reporting
|
// the field name so that we can do some nice error reporting
|
||||||
// later on in typeck.
|
// later on in typeck.
|
||||||
let traits = self.traits_in_scope(ident, ValueNS);
|
let traits = self.traits_in_scope(ident, ValueNS);
|
||||||
self.r.trait_map.as_mut().unwrap().insert(expr.id, traits);
|
self.r.trait_map.insert(expr.id, traits);
|
||||||
}
|
}
|
||||||
ExprKind::MethodCall(ref segment, ..) => {
|
ExprKind::MethodCall(ref segment, ..) => {
|
||||||
debug!("(recording candidate traits for expr) recording traits for {}", expr.id);
|
debug!("(recording candidate traits for expr) recording traits for {}", expr.id);
|
||||||
let traits = self.traits_in_scope(segment.ident, ValueNS);
|
let traits = self.traits_in_scope(segment.ident, ValueNS);
|
||||||
self.r.trait_map.as_mut().unwrap().insert(expr.id, traits);
|
self.r.trait_map.insert(expr.id, traits);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
|
|
|
@ -930,7 +930,7 @@ pub struct Resolver<'a> {
|
||||||
/// `CrateNum` resolutions of `extern crate` items.
|
/// `CrateNum` resolutions of `extern crate` items.
|
||||||
extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
|
extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
|
||||||
export_map: ExportMap,
|
export_map: ExportMap,
|
||||||
trait_map: Option<NodeMap<Vec<TraitCandidate>>>,
|
trait_map: NodeMap<Vec<TraitCandidate>>,
|
||||||
|
|
||||||
/// A map from nodes to anonymous modules.
|
/// A map from nodes to anonymous modules.
|
||||||
/// Anonymous modules are pseudo-modules that are implicitly created around items
|
/// Anonymous modules are pseudo-modules that are implicitly created around items
|
||||||
|
@ -1185,8 +1185,8 @@ impl ResolverAstLowering for Resolver<'_> {
|
||||||
self.next_node_id()
|
self.next_node_id()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn take_trait_map(&mut self) -> NodeMap<Vec<TraitCandidate>> {
|
fn take_trait_map(&mut self, node: NodeId) -> Option<Vec<TraitCandidate>> {
|
||||||
std::mem::replace(&mut self.trait_map, None).unwrap()
|
self.trait_map.remove(&node)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {
|
fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {
|
||||||
|
@ -1363,7 +1363,7 @@ impl<'a> Resolver<'a> {
|
||||||
label_res_map: Default::default(),
|
label_res_map: Default::default(),
|
||||||
extern_crate_map: Default::default(),
|
extern_crate_map: Default::default(),
|
||||||
export_map: FxHashMap::default(),
|
export_map: FxHashMap::default(),
|
||||||
trait_map: Some(NodeMap::default()),
|
trait_map: NodeMap::default(),
|
||||||
underscore_disambiguator: 0,
|
underscore_disambiguator: 0,
|
||||||
empty_module,
|
empty_module,
|
||||||
module_map,
|
module_map,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue