path::{ImportAlias, ModPath, PathKind},
per_ns::PerNs,
visibility::{RawVisibility, Visibility},
- AdtId, AstId, AstIdWithPath, ConstLoc, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern,
- LocalModuleId, ModuleDefId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc,
- UnresolvedMacro,
+ AdtId, AstId, AstIdWithPath, ConstLoc, EnumLoc, EnumVariantId, ExternBlockLoc, FunctionLoc,
+ ImplLoc, Intern, ItemContainerId, LocalModuleId, ModuleDefId, StaticLoc, StructLoc, TraitLoc,
+ TypeAliasLoc, UnionLoc, UnresolvedMacro,
};
static GLOB_RECURSION_LIMIT: Limit = Limit::new(100);
module_id: LocalModuleId,
depth: usize,
kind: MacroDirectiveKind,
+ container: ItemContainerId,
}
#[derive(Clone, Debug, Eq, PartialEq)]
enum MacroDirectiveKind {
FnLike { ast_id: AstIdWithPath<ast::MacroCall>, expand_to: ExpandTo },
- Derive { ast_id: AstIdWithPath<ast::Item>, derive_attr: AttrId },
+ Derive { ast_id: AstIdWithPath<ast::Item>, derive_attr: AttrId, derive_pos: usize },
Attr { ast_id: AstIdWithPath<ast::Item>, attr: Attr, mod_item: ModItem, tree: TreeId },
}
item_tree: &item_tree,
mod_dir: ModDir::root(),
}
- .collect(item_tree.top_level_items());
+ .collect_in_top_module(item_tree.top_level_items());
}
}
item_tree: &item_tree,
mod_dir: ModDir::root(),
}
- .collect(item_tree.top_level_items());
+ .collect_in_top_module(item_tree.top_level_items());
}
}
item_tree: &item_tree,
mod_dir,
}
- .collect(&[*mod_item]);
+ .collect(&[*mod_item], directive.container);
true
} else {
false
&mut |_err| (),
);
if let Ok(Ok(call_id)) = call_id {
- resolved.push((directive.module_id, call_id, directive.depth));
+ resolved.push((
+ directive.module_id,
+ call_id,
+ directive.depth,
+ directive.container,
+ ));
res = ReachedFixedPoint::No;
return false;
}
}
- MacroDirectiveKind::Derive { ast_id, derive_attr } => {
+ MacroDirectiveKind::Derive { ast_id, derive_attr, derive_pos } => {
let call_id = derive_macro_as_call_id(
ast_id,
*derive_attr,
&resolver,
);
if let Ok(call_id) = call_id {
- self.def_map.modules[directive.module_id].scope.add_derive_macro_invoc(
+ self.def_map.modules[directive.module_id].scope.set_derive_macro_invoc(
ast_id.ast_id,
call_id,
*derive_attr,
+ *derive_pos,
);
- resolved.push((directive.module_id, call_id, directive.depth));
+ resolved.push((
+ directive.module_id,
+ call_id,
+ directive.depth,
+ directive.container,
+ ));
res = ReachedFixedPoint::No;
return false;
}
item_tree: &item_tree,
mod_dir,
}
- .collect(&[*mod_item]);
+ .collect(&[*mod_item], directive.container);
res = ReachedFixedPoint::No;
false
};
match attr.parse_derive() {
Some(derive_macros) => {
- for path in derive_macros {
+ let mut len = 0;
+ for (idx, path) in derive_macros.enumerate() {
let ast_id = AstIdWithPath::new(file_id, ast_id.value, path);
self.unresolved_macros.push(MacroDirective {
module_id: directive.module_id,
kind: MacroDirectiveKind::Derive {
ast_id,
derive_attr: attr.id,
+ derive_pos: idx,
},
+ container: directive.container,
});
+ len = idx;
}
+
+ self.def_map.modules[directive.module_id]
+ .scope
+ .init_derive_attribute(ast_id, attr.id, len + 1);
}
None => {
let diag = DefDiagnostic::malformed_derive(
.scope
.add_attr_macro_invoc(ast_id, call_id);
- resolved.push((directive.module_id, call_id, directive.depth));
+ resolved.push((
+ directive.module_id,
+ call_id,
+ directive.depth,
+ directive.container,
+ ));
res = ReachedFixedPoint::No;
return false;
}
// Attribute resolution can add unresolved macro invocations, so concatenate the lists.
self.unresolved_macros.extend(macros);
- for (module_id, macro_call_id, depth) in resolved {
- self.collect_macro_expansion(module_id, macro_call_id, depth);
+ for (module_id, macro_call_id, depth, container) in resolved {
+ self.collect_macro_expansion(module_id, macro_call_id, depth, container);
}
res
module_id: LocalModuleId,
macro_call_id: MacroCallId,
depth: usize,
+ container: ItemContainerId,
) {
if EXPANSION_DEPTH_LIMIT.check(depth).is_err() {
cov_mark::hit!(macro_expansion_overflow);
item_tree: &item_tree,
mod_dir,
}
- .collect(item_tree.top_level_items());
+ .collect(item_tree.top_level_items(), container);
}
fn finish(mut self) -> DefMap {
}
impl ModCollector<'_, '_> {
- fn collect(&mut self, items: &[ModItem]) {
+ fn collect_in_top_module(&mut self, items: &[ModItem]) {
+ let module = self.def_collector.def_map.module_id(self.module_id);
+ self.collect(items, module.into())
+ }
+
+ fn collect(&mut self, items: &[ModItem], container: ItemContainerId) {
struct DefData<'a> {
id: ModuleDefId,
name: &'a Name,
}
}
- if let Err(()) = self.resolve_attributes(&attrs, item) {
+ if let Err(()) = self.resolve_attributes(&attrs, item, container) {
// Do not process the item. It has at least one non-builtin attribute, so the
// fixed-point algorithm is required to resolve the rest of them.
continue;
status: PartialResolvedImport::Unresolved,
})
}
- ModItem::ExternBlock(block) => self.collect(&self.item_tree[block].children),
- ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac]),
+ ModItem::ExternBlock(block) => self.collect(
+ &self.item_tree[block].children,
+ ItemContainerId::ExternBlockId(
+ ExternBlockLoc {
+ container: module,
+ id: ItemTreeId::new(self.tree_id, block),
+ }
+ .intern(self.def_collector.db),
+ ),
+ ),
+ ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac], container),
ModItem::MacroRules(id) => self.collect_macro_rules(id),
ModItem::MacroDef(id) => self.collect_macro_def(id),
ModItem::Impl(imp) => {
self.collect_proc_macro_def(&func.name, ast_id, &attrs);
def = Some(DefData {
- id: FunctionLoc {
- container: module.into(),
- id: ItemTreeId::new(self.tree_id, id),
- }
- .intern(self.def_collector.db)
- .into(),
+ id: FunctionLoc { container, id: ItemTreeId::new(self.tree_id, id) }
+ .intern(self.def_collector.db)
+ .into(),
name: &func.name,
visibility: &self.item_tree[func.visibility],
has_constructor: false,
}
ModItem::Const(id) => {
let it = &self.item_tree[id];
- let const_id = ConstLoc {
- container: module.into(),
- id: ItemTreeId::new(self.tree_id, id),
- }
- .intern(self.def_collector.db);
+ let const_id = ConstLoc { container, id: ItemTreeId::new(self.tree_id, id) }
+ .intern(self.def_collector.db);
match &it.name {
Some(name) => {
let it = &self.item_tree[id];
def = Some(DefData {
- id: StaticLoc { container: module, id: ItemTreeId::new(self.tree_id, id) }
+ id: StaticLoc { container, id: ItemTreeId::new(self.tree_id, id) }
.intern(self.def_collector.db)
.into(),
name: &it.name,
let it = &self.item_tree[id];
def = Some(DefData {
- id: TypeAliasLoc {
- container: module.into(),
- id: ItemTreeId::new(self.tree_id, id),
- }
- .intern(self.def_collector.db)
- .into(),
+ id: TypeAliasLoc { container, id: ItemTreeId::new(self.tree_id, id) }
+ .intern(self.def_collector.db)
+ .into(),
name: &it.name,
visibility: &self.item_tree[it.visibility],
has_constructor: false,
item_tree: self.item_tree,
mod_dir,
}
- .collect(&*items);
+ .collect_in_top_module(&*items);
if is_macro_use {
self.import_all_legacy_macros(module_id);
}
item_tree: &item_tree,
mod_dir,
}
- .collect(item_tree.top_level_items());
+ .collect_in_top_module(item_tree.top_level_items());
let is_macro_use = is_macro_use
|| item_tree
.top_level_attrs(db, self.def_collector.def_map.krate)
///
/// If `ignore_up_to` is `Some`, attributes preceding and including that attribute will be
/// assumed to be resolved already.
- fn resolve_attributes(&mut self, attrs: &Attrs, mod_item: ModItem) -> Result<(), ()> {
+ fn resolve_attributes(
+ &mut self,
+ attrs: &Attrs,
+ mod_item: ModItem,
+ container: ItemContainerId,
+ ) -> Result<(), ()> {
let mut ignore_up_to =
self.def_collector.skip_attrs.get(&InFile::new(self.file_id(), mod_item)).copied();
let iter = attrs
mod_item,
tree: self.tree_id,
},
+ container,
});
return Err(());
);
}
- fn collect_macro_call(&mut self, mac: &MacroCall) {
+ fn collect_macro_call(&mut self, mac: &MacroCall, container: ItemContainerId) {
let ast_id = AstIdWithPath::new(self.file_id(), mac.ast_id, ModPath::clone(&mac.path));
// Case 1: try to resolve in legacy scope and expand macro_rules
self.module_id,
macro_call_id,
self.macro_depth + 1,
+ container,
);
if let Some(err) = error {
module_id: self.module_id,
depth: self.macro_depth + 1,
kind: MacroDirectiveKind::FnLike { ast_id, expand_to: mac.expand_to },
+ container,
});
}