Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions crates/base-db/src/fixture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ pub fn identity(_attr: TokenStream, item: TokenStream) -> TokenStream {
ProcMacro {
name: "identity".into(),
kind: crate::ProcMacroKind::Attr,
ignored: false,
expander: sync::Arc::new(IdentityProcMacroExpander),
},
),
Expand All @@ -363,6 +364,7 @@ pub fn derive_identity(item: TokenStream) -> TokenStream {
ProcMacro {
name: "DeriveIdentity".into(),
kind: crate::ProcMacroKind::CustomDerive,
ignored: false,
expander: sync::Arc::new(IdentityProcMacroExpander),
},
),
Expand All @@ -377,6 +379,7 @@ pub fn input_replace(attr: TokenStream, _item: TokenStream) -> TokenStream {
ProcMacro {
name: "input_replace".into(),
kind: crate::ProcMacroKind::Attr,
ignored: false,
expander: sync::Arc::new(AttributeInputReplaceProcMacroExpander),
},
),
Expand All @@ -391,6 +394,7 @@ pub fn mirror(input: TokenStream) -> TokenStream {
ProcMacro {
name: "mirror".into(),
kind: crate::ProcMacroKind::FuncLike,
ignored: false,
expander: sync::Arc::new(MirrorProcMacroExpander),
},
),
Expand All @@ -405,6 +409,7 @@ pub fn shorten(input: TokenStream) -> TokenStream {
ProcMacro {
name: "shorten".into(),
kind: crate::ProcMacroKind::FuncLike,
ignored: false,
expander: sync::Arc::new(ShortenProcMacroExpander),
},
),
Expand Down
3 changes: 3 additions & 0 deletions crates/base-db/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,9 @@ pub type TargetLayoutLoadResult = Result<Arc<str>, Arc<str>>;
pub struct ProcMacro {
pub name: SmolStr,
pub kind: ProcMacroKind,
/// Ignored proc macros should only be expanded
/// when we are explicitly asked to do so by the user.
pub ignored: bool,
Comment on lines +274 to +276
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, let's do things a bit differently. Instead of encoding ignoredness as a flag here, let's just add a second special ProcMacroExpander for ignored ones, samy way we hadnle the dummy expander basically. Then we don't need to fetch the loaded proc-macros everytime to check and can instead immediately check the expander at hand

pub expander: sync::Arc<dyn ProcMacroExpander>,
}

Expand Down
15 changes: 14 additions & 1 deletion crates/hir-def/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -635,11 +635,11 @@ impl<'a> AssocItemCollector<'a> {
attr,
) {
Ok(ResolvedAttr::Macro(call_id)) => {
self.attr_calls.push((ast_id, call_id));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh ... this was the reason things broke down for tracing and the like ...

// If proc attribute macro expansion is disabled, skip expanding it here
if !self.db.expand_proc_attr_macros() {
continue 'attrs;
}

let loc = self.db.lookup_intern_macro_call(call_id);
if let MacroDefKind::ProcMacro(exp, ..) = loc.def.kind {
// If there's no expander for the proc macro (e.g. the
Expand All @@ -650,8 +650,21 @@ impl<'a> AssocItemCollector<'a> {
if exp.is_dummy() {
continue 'attrs;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
continue 'attrs;
self.diagnostics.push(
DefDiagnostic::unresolved_proc_macro(
self.module_id.local_id,
loc.kind,
loc.def.krate,
),
);
continue 'attrs;

}

// We check whether the proc macro is ignored, if it is, we don't expand it.
let proc_macros = self.db.proc_macros();
let proc_macro = proc_macros.get(&loc.def.krate).and_then(|m| {
m.as_ref().ok().and_then(|m| m.get(exp.proc_macro_id().0 as usize))
});
if let Some(proc_macro) = proc_macro {
if proc_macro.ignored {
continue 'attrs;
}
}
}

self.attr_calls.push((ast_id, call_id));

let res =
self.expander.enter_expand_id::<ast::MacroItems>(self.db, call_id);
self.collect_macro_items(res, &|| loc.kind.clone());
Expand Down
1 change: 1 addition & 0 deletions crates/hir-def/src/macro_expansion_tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream
ProcMacro {
name: "identity_when_valid".into(),
kind: base_db::ProcMacroKind::Attr,
ignored: false,
expander: sync::Arc::new(IdentityWhenValidProcMacroExpander),
},
)];
Expand Down
90 changes: 70 additions & 20 deletions crates/hir-def/src/nameres/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1128,6 +1128,41 @@ impl DefCollector<'_> {
resolver_def_id,
);
if let Ok(Some(call_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;
}

// We check whether the proc macro is ignored, if it is, we don't expand it.
let proc_macros = self.db.proc_macros();
let proc_macro = proc_macros.get(&loc.def.krate).and_then(|m| {
m.as_ref()
.ok()
.and_then(|m| m.get(expander.proc_macro_id().0 as usize))
});
if let Some(proc_macro) = proc_macro {
if proc_macro.ignored {
res = ReachedFixedPoint::No;
return false;
}
}
}

push_resolved(directive, call_id);

res = ReachedFixedPoint::No;
Expand Down Expand Up @@ -1306,30 +1341,45 @@ impl DefCollector<'_> {
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!(
loc.def.kind,
match loc.def.kind {
// Skip #[test]/#[bench] expansion, which would merely result in more memory usage
// due to duplicating functions into macro expansions
MacroDefKind::BuiltInAttr(expander, _)
if expander.is_test() || expander.is_bench()
) {
return recollect_without(self);
}
if expander.is_test() || expander.is_bench() =>
{
return recollect_without(self);
}
MacroDefKind::ProcMacro(expander, _, _) => {
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,
),
);

if let MacroDefKind::ProcMacro(exp, ..) = loc.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
self.def_map.diagnostics.push(DefDiagnostic::unresolved_proc_macro(
directive.module_id,
loc.kind,
loc.def.krate,
));
return recollect_without(self);
}

return recollect_without(self);
// We check whether the proc macro is ignored, if it is, we don't expand it.
let proc_macros = self.db.proc_macros();
let proc_macro = proc_macros.get(&loc.def.krate).and_then(|m| {
m.as_ref()
.ok()
.and_then(|m| m.get(expander.proc_macro_id().0 as usize))
});
if let Some(proc_macro) = proc_macro {
if proc_macro.ignored {
return recollect_without(self);
}
}
}
_ => {}
}

self.def_map.modules[directive.module_id]
Expand Down
4 changes: 4 additions & 0 deletions crates/hir-expand/src/proc_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ impl ProcMacroExpander {
self.proc_macro_id.0 == DUMMY_ID
}

pub fn proc_macro_id(&self) -> ProcMacroId {
self.proc_macro_id
}

pub fn expand(
self,
db: &dyn ExpandDatabase,
Expand Down
2 changes: 1 addition & 1 deletion crates/rust-analyzer/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1166,7 +1166,7 @@ impl Config {
Some(AbsPathBuf::try_from(path).unwrap_or_else(|path| self.root_path.join(&path)))
}

pub fn dummy_replacements(&self) -> &FxHashMap<Box<str>, Box<[Box<str>]>> {
pub fn ignored_proc_macros(&self) -> &FxHashMap<Box<str>, Box<[Box<str>]>> {
&self.data.procMacro_ignored
}

Expand Down
Loading