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;
/// The defs declared in this scope. Each def has a single scope where it is
/// declared.
declarations: Vec<ModuleDefId>,
+ macro_declarations: Vec<MacroDefId>,
+
impls: Vec<ImplId>,
unnamed_consts: Vec<ConstId>,
/// Traits imported via `use Trait as _;`.
// be all resolved to the last one defined if shadowing happens.
legacy_macros: FxHashMap<Name, MacroDefId>,
attr_macros: FxHashMap<AstId<ast::Item>, MacroCallId>,
- derive_macros: FxHashMap<AstId<ast::Item>, 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<AstId<ast::Adt>, SmallVec<[(AttrId, SmallVec<[Option<MacroCallId>; 1]>); 1]>>,
}
pub(crate) static BUILTIN_SCOPE: Lazy<FxHashMap<Name, PerNs>> = Lazy::new(|| {
self.declarations.iter().copied()
}
+ pub fn macro_declarations(&self) -> impl Iterator<Item = MacroDefId> + '_ {
+ self.macro_declarations.iter().copied()
+ }
+
pub fn impls(&self) -> impl Iterator<Item = ImplId> + ExactSizeIterator + '_ {
self.impls.iter().copied()
}
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<MacroDefId> {
self.legacy_macros.get(name).copied()
}
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<ast::Item>,
+ adt: AstId<ast::Adt>,
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<ast::Adt>,
+ 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<Item = (AstId<ast::Item>, &[(AttrId, MacroCallId)])> + '_ {
- self.derive_macros.iter().map(|(k, v)| (*k, v.as_ref()))
+ ) -> impl Iterator<
+ Item = (AstId<ast::Adt>, impl Iterator<Item = (AttrId, &[Option<MacroCallId>])>),
+ > + '_ {
+ 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<Visibility> {
values,
macros,
unresolved,
- declarations: defs,
+ declarations,
+ macro_declarations,
impls,
unnamed_consts,
unnamed_trait_imports,
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();