mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 12:29:21 +00:00
Encode disabled proc-macros via boolean flag, not special Expander
This commit is contained in:
parent
ab50ec9863
commit
e2a985e93f
8 changed files with 91 additions and 148 deletions
|
@ -653,7 +653,8 @@ impl<'a> AssocItemCollector<'a> {
|
|||
));
|
||||
|
||||
continue 'attrs;
|
||||
} else if exp.is_disabled() {
|
||||
}
|
||||
if exp.is_disabled() {
|
||||
continue 'attrs;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream
|
|||
name: "identity_when_valid".into(),
|
||||
kind: ProcMacroKind::Attr,
|
||||
expander: sync::Arc::new(IdentityWhenValidProcMacroExpander),
|
||||
disabled: false,
|
||||
},
|
||||
)];
|
||||
let db = TestDB::with_files_extra_proc_macros(ra_fixture, extra_proc_macros);
|
||||
|
|
|
@ -11,7 +11,7 @@ use either::Either;
|
|||
use hir_expand::{
|
||||
ast_id_map::FileAstId,
|
||||
attrs::{Attr, AttrId},
|
||||
builtin_attr_macro::find_builtin_attr,
|
||||
builtin_attr_macro::{find_builtin_attr, BuiltinAttrExpander},
|
||||
builtin_derive_macro::find_builtin_derive,
|
||||
builtin_fn_macro::find_builtin_macro,
|
||||
name::{name, AsName, Name},
|
||||
|
@ -98,12 +98,12 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeI
|
|||
};
|
||||
(
|
||||
name.as_name(),
|
||||
if it.expander.should_expand() {
|
||||
if it.disabled {
|
||||
CustomProcMacroExpander::disabled()
|
||||
} else {
|
||||
CustomProcMacroExpander::new(hir_expand::proc_macro::ProcMacroId(
|
||||
idx as u32,
|
||||
))
|
||||
} else {
|
||||
CustomProcMacroExpander::disabled()
|
||||
},
|
||||
)
|
||||
})
|
||||
|
@ -608,9 +608,6 @@ impl DefCollector<'_> {
|
|||
id: ItemTreeId<item_tree::Function>,
|
||||
fn_id: FunctionId,
|
||||
) {
|
||||
if self.def_map.block.is_some() {
|
||||
return;
|
||||
}
|
||||
let kind = def.kind.to_basedb_kind();
|
||||
let (expander, kind) =
|
||||
match self.proc_macros.as_ref().map(|it| it.iter().find(|(n, _)| n == &def.name)) {
|
||||
|
@ -1124,9 +1121,16 @@ impl DefCollector<'_> {
|
|||
let mut push_resolved = |directive: &MacroDirective, call_id| {
|
||||
resolved.push((directive.module_id, directive.depth, directive.container, call_id));
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
enum Resolved {
|
||||
Yes,
|
||||
No,
|
||||
}
|
||||
|
||||
let mut res = ReachedFixedPoint::Yes;
|
||||
// Retain unresolved macros after this round of resolution.
|
||||
macros.retain(|directive| {
|
||||
let mut retain = |directive: &MacroDirective| {
|
||||
let subns = match &directive.kind {
|
||||
MacroDirectiveKind::FnLike { .. } => MacroSubNs::Bang,
|
||||
MacroDirectiveKind::Attr { .. } | MacroDirectiveKind::Derive { .. } => {
|
||||
|
@ -1161,34 +1165,10 @@ impl DefCollector<'_> {
|
|||
.scope
|
||||
.add_macro_invoc(ast_id.ast_id, call_id);
|
||||
|
||||
let loc: MacroCallLoc = self.db.lookup_intern_macro_call(call_id);
|
||||
|
||||
if let MacroDefKind::ProcMacro(expander, _, _) = loc.def.kind {
|
||||
if expander.is_dummy() {
|
||||
// If there's no expander for the proc macro (e.g.
|
||||
// because proc macros are disabled, or building the
|
||||
// proc macro crate failed), report this and skip
|
||||
// expansion like we would if it was disabled
|
||||
self.def_map.diagnostics.push(
|
||||
DefDiagnostic::unresolved_proc_macro(
|
||||
directive.module_id,
|
||||
loc.kind,
|
||||
loc.def.krate,
|
||||
),
|
||||
);
|
||||
|
||||
res = ReachedFixedPoint::No;
|
||||
return false;
|
||||
} else if expander.is_disabled() {
|
||||
res = ReachedFixedPoint::No;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
push_resolved(directive, call_id);
|
||||
|
||||
res = ReachedFixedPoint::No;
|
||||
return false;
|
||||
return Resolved::Yes;
|
||||
}
|
||||
}
|
||||
MacroDirectiveKind::Derive { ast_id, derive_attr, derive_pos, call_site } => {
|
||||
|
@ -1227,7 +1207,7 @@ impl DefCollector<'_> {
|
|||
|
||||
push_resolved(directive, call_id);
|
||||
res = ReachedFixedPoint::No;
|
||||
return false;
|
||||
return Resolved::Yes;
|
||||
}
|
||||
}
|
||||
MacroDirectiveKind::Attr { ast_id: file_ast_id, mod_item, attr, tree } => {
|
||||
|
@ -1250,7 +1230,7 @@ impl DefCollector<'_> {
|
|||
}
|
||||
.collect(&[*mod_item], directive.container);
|
||||
res = ReachedFixedPoint::No;
|
||||
false
|
||||
Resolved::Yes
|
||||
};
|
||||
|
||||
if let Some(ident) = path.as_ident() {
|
||||
|
@ -1266,13 +1246,18 @@ impl DefCollector<'_> {
|
|||
|
||||
let def = match resolver_def_id(path.clone()) {
|
||||
Some(def) if def.is_attribute() => def,
|
||||
_ => return true,
|
||||
_ => return Resolved::No,
|
||||
};
|
||||
if matches!(
|
||||
def,
|
||||
MacroDefId { kind: MacroDefKind::BuiltInAttr(expander, _),.. }
|
||||
if expander.is_derive()
|
||||
) {
|
||||
|
||||
if let MacroDefId {
|
||||
kind:
|
||||
MacroDefKind::BuiltInAttr(
|
||||
BuiltinAttrExpander::Derive | BuiltinAttrExpander::DeriveConst,
|
||||
_,
|
||||
),
|
||||
..
|
||||
} = def
|
||||
{
|
||||
// Resolved to `#[derive]`, we don't actually expand this attribute like
|
||||
// normal (as that would just be an identity expansion with extra output)
|
||||
// Instead we treat derive attributes special and apply them separately.
|
||||
|
@ -1345,16 +1330,6 @@ impl DefCollector<'_> {
|
|||
let call_id =
|
||||
attr_macro_as_call_id(self.db, file_ast_id, attr, self.def_map.krate, def);
|
||||
|
||||
// If proc attribute macro expansion is disabled, skip expanding it here
|
||||
if !self.db.expand_proc_attr_macros() {
|
||||
self.def_map.diagnostics.push(DefDiagnostic::unresolved_proc_macro(
|
||||
directive.module_id,
|
||||
self.db.lookup_intern_macro_call(call_id).kind,
|
||||
def.krate,
|
||||
));
|
||||
return recollect_without(self);
|
||||
}
|
||||
|
||||
// Skip #[test]/#[bench] expansion, which would merely result in more memory usage
|
||||
// due to duplicating functions into macro expansions
|
||||
if matches!(
|
||||
|
@ -1366,19 +1341,29 @@ impl DefCollector<'_> {
|
|||
}
|
||||
|
||||
if let MacroDefKind::ProcMacro(exp, ..) = def.kind {
|
||||
if exp.is_dummy() {
|
||||
// If there's no expander for the proc macro (e.g.
|
||||
// because proc macros are disabled, or building the
|
||||
// proc macro crate failed), report this and skip
|
||||
// expansion like we would if it was disabled
|
||||
// If proc attribute macro expansion is disabled, skip expanding it here
|
||||
if !self.db.expand_proc_attr_macros() {
|
||||
self.def_map.diagnostics.push(DefDiagnostic::unresolved_proc_macro(
|
||||
directive.module_id,
|
||||
self.db.lookup_intern_macro_call(call_id).kind,
|
||||
def.krate,
|
||||
));
|
||||
|
||||
return recollect_without(self);
|
||||
} else if exp.is_disabled() {
|
||||
}
|
||||
|
||||
// If there's no expander for the proc macro (e.g.
|
||||
// because proc macros are disabled, or building the
|
||||
// proc macro crate failed), report this and skip
|
||||
// expansion like we would if it was disabled
|
||||
if exp.is_dummy() {
|
||||
self.def_map.diagnostics.push(DefDiagnostic::unresolved_proc_macro(
|
||||
directive.module_id,
|
||||
self.db.lookup_intern_macro_call(call_id).kind,
|
||||
def.krate,
|
||||
));
|
||||
return recollect_without(self);
|
||||
}
|
||||
if exp.is_disabled() {
|
||||
return recollect_without(self);
|
||||
}
|
||||
}
|
||||
|
@ -1389,12 +1374,13 @@ impl DefCollector<'_> {
|
|||
|
||||
push_resolved(directive, call_id);
|
||||
res = ReachedFixedPoint::No;
|
||||
return false;
|
||||
return Resolved::Yes;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
});
|
||||
Resolved::No
|
||||
};
|
||||
macros.retain(|it| retain(it) == Resolved::No);
|
||||
// Attribute resolution can add unresolved macro invocations, so concatenate the lists.
|
||||
macros.extend(mem::take(&mut self.unresolved_macros));
|
||||
self.unresolved_macros = macros;
|
||||
|
@ -1704,7 +1690,11 @@ impl ModCollector<'_, '_> {
|
|||
FunctionLoc { container, id: ItemTreeId::new(self.tree_id, id) }.intern(db);
|
||||
|
||||
let vis = resolve_vis(def_map, &self.item_tree[it.visibility]);
|
||||
if self.def_collector.is_proc_macro && self.module_id == DefMap::ROOT {
|
||||
|
||||
if self.def_collector.def_map.block.is_none()
|
||||
&& self.def_collector.is_proc_macro
|
||||
&& self.module_id == DefMap::ROOT
|
||||
{
|
||||
if let Some(proc_macro) = attrs.parse_proc_macro_decl(&it.name) {
|
||||
self.def_collector.export_proc_macro(
|
||||
proc_macro,
|
||||
|
|
|
@ -103,6 +103,9 @@ impl DefDiagnostic {
|
|||
}
|
||||
|
||||
// FIXME: Whats the difference between this and unresolved_macro_call
|
||||
// FIXME: This is used for a lot of things, unresolved proc macros, disabled proc macros, etc
|
||||
// yet the diagnostic handler in ide-diagnostics has to figure out what happened because this
|
||||
// struct loses all that information!
|
||||
pub(crate) fn unresolved_proc_macro(
|
||||
container: LocalModuleId,
|
||||
ast: MacroCallKind,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue