X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=crates%2Fhir_def%2Fsrc%2Fitem_scope.rs;h=258d1e0f6c5191a5c17cd97b5d3ef3ef31943344;hb=0db0dec9993b510efeb61cb1d8ff113270d4ca51;hp=0a2a6719edc1951f96aa037e62be965687633275;hpb=f724c84e7d50e8f4fe84e7842008c1e4d33ef717;p=rust.git diff --git a/crates/hir_def/src/item_scope.rs b/crates/hir_def/src/item_scope.rs index 0a2a6719edc..258d1e0f6c5 100644 --- a/crates/hir_def/src/item_scope.rs +++ b/crates/hir_def/src/item_scope.rs @@ -8,7 +8,7 @@ use once_cell::sync::Lazy; use profile::Count; use rustc_hash::{FxHashMap, FxHashSet}; -use smallvec::SmallVec; +use smallvec::{smallvec, SmallVec}; use stdx::format_to; use syntax::ast; @@ -44,6 +44,8 @@ pub struct ItemScope { /// The defs declared in this scope. Each def has a single scope where it is /// declared. declarations: Vec, + macro_declarations: Vec, + impls: Vec, unnamed_consts: Vec, /// Traits imported via `use Trait as _;`. @@ -62,7 +64,10 @@ pub struct ItemScope { // be all resolved to the last one defined if shadowing happens. legacy_macros: FxHashMap, attr_macros: FxHashMap, MacroCallId>, - derive_macros: FxHashMap, SmallVec<[(AttrId, MacroCallId); 1]>>, + /// The derive macro invocations in this scope, keyed by the owner item over the actual derive attributes + /// paired with the derive macro invocations for the specific attribute. + derive_macros: + FxHashMap, SmallVec<[(AttrId, SmallVec<[Option; 1]>); 1]>>, } pub(crate) static BUILTIN_SCOPE: Lazy> = Lazy::new(|| { @@ -101,6 +106,10 @@ pub fn declarations(&self) -> impl Iterator + '_ { self.declarations.iter().copied() } + pub fn macro_declarations(&self) -> impl Iterator + '_ { + self.macro_declarations.iter().copied() + } + pub fn impls(&self) -> impl Iterator + ExactSizeIterator + '_ { self.impls.iter().copied() } @@ -163,6 +172,10 @@ pub(crate) fn declare(&mut self, def: ModuleDefId) { self.declarations.push(def) } + pub(crate) fn declare_macro(&mut self, def: MacroDefId) { + self.macro_declarations.push(def); + } + pub(crate) fn get_legacy_macro(&self, name: &Name) -> Option { self.legacy_macros.get(name).copied() } @@ -189,19 +202,40 @@ pub(crate) fn attr_macro_invocs( self.attr_macros.iter().map(|(k, v)| (*k, *v)) } - pub(crate) fn add_derive_macro_invoc( + pub(crate) fn set_derive_macro_invoc( &mut self, - item: AstId, + adt: AstId, call: MacroCallId, attr_id: AttrId, + idx: usize, + ) { + if let Some(derives) = self.derive_macros.get_mut(&adt) { + if let Some((_, invocs)) = derives.iter_mut().find(|&&mut (id, _)| id == attr_id) { + invocs[idx] = Some(call); + } + } + } + + /// We are required to set this up front as derive invocation recording happens out of order + /// due to the fixed pointer iteration loop being able to record some derives later than others + /// independent of their indices. + pub(crate) fn init_derive_attribute( + &mut self, + adt: AstId, + attr_id: AttrId, + len: usize, ) { - self.derive_macros.entry(item).or_default().push((attr_id, call)); + self.derive_macros.entry(adt).or_default().push((attr_id, smallvec![None; len])); } pub(crate) fn derive_macro_invocs( &self, - ) -> impl Iterator, &[(AttrId, MacroCallId)])> + '_ { - self.derive_macros.iter().map(|(k, v)| (*k, v.as_ref())) + ) -> impl Iterator< + Item = (AstId, impl Iterator])>), + > + '_ { + self.derive_macros + .iter() + .map(|(k, v)| (*k, v.iter().map(|(attr_id, invocs)| (*attr_id, &**invocs)))) } pub(crate) fn unnamed_trait_vis(&self, tr: TraitId) -> Option { @@ -336,7 +370,8 @@ pub(crate) fn shrink_to_fit(&mut self) { values, macros, unresolved, - declarations: defs, + declarations, + macro_declarations, impls, unnamed_consts, unnamed_trait_imports, @@ -348,7 +383,8 @@ pub(crate) fn shrink_to_fit(&mut self) { values.shrink_to_fit(); macros.shrink_to_fit(); unresolved.shrink_to_fit(); - defs.shrink_to_fit(); + declarations.shrink_to_fit(); + macro_declarations.shrink_to_fit(); impls.shrink_to_fit(); unnamed_consts.shrink_to_fit(); unnamed_trait_imports.shrink_to_fit();