Skip to content

Commit f6e2fca

Browse files
committed
Internal: Cleanup proc-macro error handling
1 parent 4a6b461 commit f6e2fca

File tree

39 files changed

+380
-522
lines changed

39 files changed

+380
-522
lines changed

src/tools/rust-analyzer/crates/base-db/src/input.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ use span::{Edition, EditionedFileId};
1616
use triomphe::Arc;
1717
use vfs::{file_set::FileSet, AbsPathBuf, AnchoredPath, FileId, VfsPath};
1818

19-
// Map from crate id to the name of the crate and path of the proc-macro. If the value is `None`,
20-
// then the crate for the proc-macro hasn't been build yet as the build data is missing.
21-
pub type ProcMacroPaths = FxHashMap<CrateId, Result<(Option<String>, AbsPathBuf), String>>;
19+
pub type ProcMacroPaths = FxHashMap<CrateId, Result<(String, AbsPathBuf), String>>;
2220

2321
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
2422
pub struct SourceRootId(pub u32);

src/tools/rust-analyzer/crates/hir-def/src/body.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::ops::{Deref, Index};
1010

1111
use base_db::CrateId;
1212
use cfg::{CfgExpr, CfgOptions};
13-
use hir_expand::{name::Name, InFile};
13+
use hir_expand::{name::Name, ExpandError, InFile};
1414
use la_arena::{Arena, ArenaMap, Idx, RawIdx};
1515
use rustc_hash::FxHashMap;
1616
use smallvec::SmallVec;
@@ -115,8 +115,7 @@ pub struct SyntheticSyntax;
115115
#[derive(Debug, Eq, PartialEq)]
116116
pub enum BodyDiagnostic {
117117
InactiveCode { node: InFile<SyntaxNodePtr>, cfg: CfgExpr, opts: CfgOptions },
118-
MacroError { node: InFile<AstPtr<ast::MacroCall>>, message: String },
119-
UnresolvedProcMacro { node: InFile<AstPtr<ast::MacroCall>>, krate: CrateId },
118+
MacroError { node: InFile<AstPtr<ast::MacroCall>>, err: ExpandError },
120119
UnresolvedMacroCall { node: InFile<AstPtr<ast::MacroCall>>, path: ModPath },
121120
UnreachableLabel { node: InFile<AstPtr<ast::Lifetime>>, name: Name },
122121
UndeclaredLabel { node: InFile<AstPtr<ast::Lifetime>>, name: Name },

src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use base_db::CrateId;
77
use either::Either;
88
use hir_expand::{
99
name::{AsName, Name},
10-
ExpandError, InFile,
10+
InFile,
1111
};
1212
use intern::{sym, Interned, Symbol};
1313
use rustc_hash::FxHashMap;
@@ -992,20 +992,11 @@ impl ExprCollector<'_> {
992992
}
993993
};
994994
if record_diagnostics {
995-
match &res.err {
996-
Some(ExpandError::UnresolvedProcMacro(krate)) => {
997-
self.source_map.diagnostics.push(BodyDiagnostic::UnresolvedProcMacro {
998-
node: InFile::new(outer_file, syntax_ptr),
999-
krate: *krate,
1000-
});
1001-
}
1002-
Some(err) => {
1003-
self.source_map.diagnostics.push(BodyDiagnostic::MacroError {
1004-
node: InFile::new(outer_file, syntax_ptr),
1005-
message: err.to_string(),
1006-
});
1007-
}
1008-
None => {}
995+
if let Some(err) = res.err {
996+
self.source_map.diagnostics.push(BodyDiagnostic::MacroError {
997+
node: InFile::new(outer_file, syntax_ptr),
998+
err,
999+
});
10091000
}
10101001
}
10111002

src/tools/rust-analyzer/crates/hir-def/src/data.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -657,22 +657,17 @@ impl<'a> AssocItemCollector<'a> {
657657
// crate failed), skip expansion like we would if it was
658658
// disabled. This is analogous to the handling in
659659
// `DefCollector::collect_macros`.
660-
if exp.is_dummy() {
661-
self.diagnostics.push(DefDiagnostic::unresolved_proc_macro(
660+
if let Some(err) = exp.as_expand_error(self.module_id.krate) {
661+
self.diagnostics.push(DefDiagnostic::macro_error(
662662
self.module_id.local_id,
663-
loc.kind,
664-
loc.def.krate,
663+
ast_id,
664+
err,
665665
));
666-
667-
continue 'attrs;
668-
}
669-
if exp.is_disabled() {
670666
continue 'attrs;
671667
}
672668
}
673669

674670
self.macro_calls.push((ast_id, call_id));
675-
676671
let res =
677672
self.expander.enter_expand_id::<ast::MacroItems>(self.db, call_id);
678673
self.collect_macro_items(res);

src/tools/rust-analyzer/crates/hir-def/src/expander.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ impl Expander {
179179
value: match err {
180180
// If proc-macro is disabled or unresolved, we want to expand to a missing expression
181181
// instead of an empty tree which might end up in an empty block.
182-
Some(ExpandError::UnresolvedProcMacro(_)) => None,
182+
Some(ExpandError::MissingProcMacroExpander(_)) => None,
183183
_ => (|| {
184184
let parse = res.value.0.cast::<T>()?;
185185

src/tools/rust-analyzer/crates/hir-def/src/lib.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,7 @@ use base_db::{
7575
CrateId,
7676
};
7777
use hir_expand::{
78-
builtin_attr_macro::BuiltinAttrExpander,
79-
builtin_derive_macro::BuiltinDeriveExpander,
80-
builtin_fn_macro::{BuiltinFnLikeExpander, EagerExpander},
78+
builtin::{BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerExpander},
8179
db::ExpandDatabase,
8280
eager::expand_eager_macro_input,
8381
impl_intern_lookup,

src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream
122122

123123
let mut expn_text = String::new();
124124
if let Some(err) = exp.err {
125-
format_to!(expn_text, "/* error: {} */", err);
125+
format_to!(expn_text, "/* error: {} */", err.render_to_string(&db).0);
126126
}
127127
let (parse, token_map) = exp.value;
128128
if expect_errors {

src/tools/rust-analyzer/crates/hir-def/src/nameres.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,6 @@ struct DefMapCrateData {
145145
/// Side table for resolving derive helpers.
146146
exported_derives: FxHashMap<MacroDefId, Box<[Name]>>,
147147
fn_proc_macro_mapping: FxHashMap<FunctionId, ProcMacroId>,
148-
/// The error that occurred when failing to load the proc-macro dll.
149-
proc_macro_loading_error: Option<Box<str>>,
150148

151149
/// Custom attributes registered with `#![register_attr]`.
152150
registered_attrs: Vec<Symbol>,
@@ -169,7 +167,6 @@ impl DefMapCrateData {
169167
extern_prelude: FxIndexMap::default(),
170168
exported_derives: FxHashMap::default(),
171169
fn_proc_macro_mapping: FxHashMap::default(),
172-
proc_macro_loading_error: None,
173170
registered_attrs: Vec::new(),
174171
registered_tools: PREDEFINED_TOOLS.iter().map(|it| Symbol::intern(it)).collect(),
175172
unstable_features: FxHashSet::default(),
@@ -189,7 +186,6 @@ impl DefMapCrateData {
189186
registered_attrs,
190187
registered_tools,
191188
unstable_features,
192-
proc_macro_loading_error: _,
193189
rustc_coherence_is_core: _,
194190
no_core: _,
195191
no_std: _,
@@ -474,10 +470,6 @@ impl DefMap {
474470
self.data.fn_proc_macro_mapping.get(&id).copied()
475471
}
476472

477-
pub fn proc_macro_loading_error(&self) -> Option<&str> {
478-
self.data.proc_macro_loading_error.as_deref()
479-
}
480-
481473
pub fn krate(&self) -> CrateId {
482474
self.krate
483475
}

src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs

Lines changed: 26 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ use cfg::{CfgExpr, CfgOptions};
1010
use either::Either;
1111
use hir_expand::{
1212
attrs::{Attr, AttrId},
13-
builtin_attr_macro::find_builtin_attr,
14-
builtin_derive_macro::find_builtin_derive,
15-
builtin_fn_macro::find_builtin_macro,
13+
builtin::{find_builtin_attr, find_builtin_derive, find_builtin_macro},
1614
name::{AsName, Name},
1715
proc_macro::CustomProcMacroExpander,
1816
ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind,
@@ -76,34 +74,11 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeI
7674
}
7775

7876
let proc_macros = if krate.is_proc_macro {
79-
match db.proc_macros().get(&def_map.krate) {
80-
Some(Ok(proc_macros)) => Ok({
81-
let ctx = db.syntax_context(tree_id.file_id());
82-
proc_macros
83-
.iter()
84-
.enumerate()
85-
.map(|(idx, it)| {
86-
let name = Name::new_symbol(it.name.clone(), ctx);
87-
(
88-
name,
89-
if !db.expand_proc_attr_macros() {
90-
CustomProcMacroExpander::dummy()
91-
} else if it.disabled {
92-
CustomProcMacroExpander::disabled()
93-
} else {
94-
CustomProcMacroExpander::new(
95-
hir_expand::proc_macro::ProcMacroId::new(idx as u32),
96-
)
97-
},
98-
)
99-
})
100-
.collect()
101-
}),
102-
Some(Err(e)) => Err(e.clone().into_boxed_str()),
103-
None => Err("No proc-macros present for crate".to_owned().into_boxed_str()),
104-
}
77+
db.proc_macros()
78+
.for_crate(def_map.krate, db.syntax_context(tree_id.file_id()))
79+
.unwrap_or_default()
10580
} else {
106-
Ok(vec![])
81+
Default::default()
10782
};
10883

10984
let mut collector = DefCollector {
@@ -252,10 +227,10 @@ struct DefCollector<'a> {
252227
mod_dirs: FxHashMap<LocalModuleId, ModDir>,
253228
cfg_options: &'a CfgOptions,
254229
/// List of procedural macros defined by this crate. This is read from the dynamic library
255-
/// built by the build system, and is the list of proc. macros we can actually expand. It is
256-
/// empty when proc. macro support is disabled (in which case we still do name resolution for
257-
/// them).
258-
proc_macros: Result<Vec<(Name, CustomProcMacroExpander)>, Box<str>>,
230+
/// built by the build system, and is the list of proc-macros we can actually expand. It is
231+
/// empty when proc-macro support is disabled (in which case we still do name resolution for
232+
/// them). The bool signals whether the proc-macro has been explicitly disabled for name-resolution.
233+
proc_macros: Box<[(Name, CustomProcMacroExpander, bool)]>,
259234
is_proc_macro: bool,
260235
from_glob_import: PerNsGlobImports,
261236
/// If we fail to resolve an attribute on a `ModItem`, we fall back to ignoring the attribute.
@@ -278,10 +253,6 @@ impl DefCollector<'_> {
278253
let attrs = item_tree.top_level_attrs(self.db, self.def_map.krate);
279254
let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap();
280255

281-
if let Err(e) = &self.proc_macros {
282-
crate_data.proc_macro_loading_error = Some(e.clone());
283-
}
284-
285256
let mut process = true;
286257

287258
// Process other crate-level attributes.
@@ -608,11 +579,17 @@ impl DefCollector<'_> {
608579
fn_id: FunctionId,
609580
) {
610581
let kind = def.kind.to_basedb_kind();
611-
let (expander, kind) =
612-
match self.proc_macros.as_ref().map(|it| it.iter().find(|(n, _)| n == &def.name)) {
613-
Ok(Some(&(_, expander))) => (expander, kind),
614-
_ => (CustomProcMacroExpander::dummy(), kind),
615-
};
582+
let (expander, kind) = match self.proc_macros.iter().find(|(n, _, _)| n == &def.name) {
583+
Some(_)
584+
if kind == hir_expand::proc_macro::ProcMacroKind::Attr
585+
&& !self.db.expand_proc_attr_macros() =>
586+
{
587+
(CustomProcMacroExpander::disabled_proc_attr(), kind)
588+
}
589+
Some(&(_, _, true)) => (CustomProcMacroExpander::disabled(), kind),
590+
Some(&(_, expander, false)) => (expander, kind),
591+
None => (CustomProcMacroExpander::missing_expander(), kind),
592+
};
616593

617594
let proc_macro_id = ProcMacroLoc {
618595
container: self.def_map.crate_root(),
@@ -1338,25 +1315,22 @@ impl DefCollector<'_> {
13381315
return recollect_without(self);
13391316
}
13401317

1341-
let call_id = call_id();
13421318
if let MacroDefKind::ProcMacro(_, exp, _) = def.kind {
13431319
// If there's no expander for the proc macro (e.g.
13441320
// because proc macros are disabled, or building the
13451321
// proc macro crate failed), report this and skip
13461322
// expansion like we would if it was disabled
1347-
if exp.is_dummy() {
1348-
self.def_map.diagnostics.push(DefDiagnostic::unresolved_proc_macro(
1323+
if let Some(err) = exp.as_expand_error(def.krate) {
1324+
self.def_map.diagnostics.push(DefDiagnostic::macro_error(
13491325
directive.module_id,
1350-
self.db.lookup_intern_macro_call(call_id).kind,
1351-
def.krate,
1326+
ast_id,
1327+
err,
13521328
));
13531329
return recollect_without(self);
13541330
}
1355-
if exp.is_disabled() {
1356-
return recollect_without(self);
1357-
}
13581331
}
13591332

1333+
let call_id = call_id();
13601334
self.def_map.modules[directive.module_id]
13611335
.scope
13621336
.add_attr_macro_invoc(ast_id, call_id);
@@ -1395,7 +1369,6 @@ impl DefCollector<'_> {
13951369
}
13961370
let file_id = macro_call_id.as_file();
13971371

1398-
// Then, fetch and process the item tree. This will reuse the expansion result from above.
13991372
let item_tree = self.db.file_item_tree(file_id);
14001373

14011374
let mod_dir = if macro_call_id.as_macro_file().is_include_macro(self.db.upcast()) {
@@ -2433,7 +2406,7 @@ mod tests {
24332406
unresolved_macros: Vec::new(),
24342407
mod_dirs: FxHashMap::default(),
24352408
cfg_options: &CfgOptions::default(),
2436-
proc_macros: Ok(vec![]),
2409+
proc_macros: Default::default(),
24372410
from_glob_import: Default::default(),
24382411
skip_attrs: Default::default(),
24392412
is_proc_macro: false,

src/tools/rust-analyzer/crates/hir-def/src/nameres/diagnostics.rs

Lines changed: 15 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
33
use std::ops::Not;
44

5-
use base_db::CrateId;
65
use cfg::{CfgExpr, CfgOptions};
7-
use hir_expand::{attrs::AttrId, MacroCallKind};
6+
use hir_expand::{attrs::AttrId, ExpandError, MacroCallKind};
87
use la_arena::Idx;
98
use syntax::ast;
109

@@ -17,48 +16,16 @@ use crate::{
1716

1817
#[derive(Debug, PartialEq, Eq)]
1918
pub enum DefDiagnosticKind {
20-
UnresolvedModule {
21-
ast: AstId<ast::Module>,
22-
candidates: Box<[String]>,
23-
},
24-
UnresolvedExternCrate {
25-
ast: AstId<ast::ExternCrate>,
26-
},
27-
UnresolvedImport {
28-
id: ItemTreeId<item_tree::Use>,
29-
index: Idx<ast::UseTree>,
30-
},
31-
UnconfiguredCode {
32-
tree: TreeId,
33-
item: AttrOwner,
34-
cfg: CfgExpr,
35-
opts: CfgOptions,
36-
},
37-
/// A proc-macro that is lacking an expander, this might be due to build scripts not yet having
38-
/// run or proc-macro expansion being disabled.
39-
UnresolvedProcMacro {
40-
ast: MacroCallKind,
41-
krate: CrateId,
42-
},
43-
UnresolvedMacroCall {
44-
ast: MacroCallKind,
45-
path: ModPath,
46-
},
47-
UnimplementedBuiltinMacro {
48-
ast: AstId<ast::Macro>,
49-
},
50-
InvalidDeriveTarget {
51-
ast: AstId<ast::Item>,
52-
id: usize,
53-
},
54-
MalformedDerive {
55-
ast: AstId<ast::Adt>,
56-
id: usize,
57-
},
58-
MacroDefError {
59-
ast: AstId<ast::Macro>,
60-
message: String,
61-
},
19+
UnresolvedModule { ast: AstId<ast::Module>, candidates: Box<[String]> },
20+
UnresolvedExternCrate { ast: AstId<ast::ExternCrate> },
21+
UnresolvedImport { id: ItemTreeId<item_tree::Use>, index: Idx<ast::UseTree> },
22+
UnconfiguredCode { tree: TreeId, item: AttrOwner, cfg: CfgExpr, opts: CfgOptions },
23+
UnresolvedMacroCall { ast: MacroCallKind, path: ModPath },
24+
UnimplementedBuiltinMacro { ast: AstId<ast::Macro> },
25+
InvalidDeriveTarget { ast: AstId<ast::Item>, id: usize },
26+
MalformedDerive { ast: AstId<ast::Adt>, id: usize },
27+
MacroDefError { ast: AstId<ast::Macro>, message: String },
28+
MacroError { ast: AstId<ast::Item>, err: ExpandError },
6229
}
6330

6431
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -115,6 +82,10 @@ impl DefDiagnostic {
11582
Self { in_module: container, kind: DefDiagnosticKind::UnresolvedImport { id, index } }
11683
}
11784

85+
pub fn macro_error(container: LocalModuleId, ast: AstId<ast::Item>, err: ExpandError) -> Self {
86+
Self { in_module: container, kind: DefDiagnosticKind::MacroError { ast, err } }
87+
}
88+
11889
pub fn unconfigured_code(
11990
container: LocalModuleId,
12091
tree: TreeId,
@@ -128,14 +99,6 @@ impl DefDiagnostic {
12899
}
129100
}
130101

131-
pub fn unresolved_proc_macro(
132-
container: LocalModuleId,
133-
ast: MacroCallKind,
134-
krate: CrateId,
135-
) -> Self {
136-
Self { in_module: container, kind: DefDiagnosticKind::UnresolvedProcMacro { ast, krate } }
137-
}
138-
139102
// FIXME: Whats the difference between this and unresolved_proc_macro
140103
pub(crate) fn unresolved_macro_call(
141104
container: LocalModuleId,

0 commit comments

Comments
 (0)