Improve proc macro errors a bit

Distinguish between
 - there is no build data (for some reason?)
 - there is build data, but the cargo package didn't build a proc macro dylib
 - there is a proc macro dylib, but it didn't contain the proc macro we expected
 - the name did not resolve to any macro (this is now an
 unresolved_macro_call even for attributes)

I changed the handling of disabled attribute macro expansion to
immediately ignore the macro and report an unresolved_proc_macro,
because otherwise they would now result in loud unresolved_macro_call
errors. I hope this doesn't break anything.

Also try to improve error ranges for unresolved_macro_call / macro_error
by reusing the code for unresolved_proc_macro. It's not perfect but
probably better than before.
This commit is contained in:
Florian Diebold 2022-06-24 13:03:13 +02:00
parent 32b40ded0f
commit c80c34867f
10 changed files with 164 additions and 163 deletions

1
Cargo.lock generated
View file

@ -538,6 +538,7 @@ dependencies = [
"mbe", "mbe",
"profile", "profile",
"rustc-hash", "rustc-hash",
"stdx",
"syntax", "syntax",
"tracing", "tracing",
"tt", "tt",

View file

@ -436,7 +436,7 @@ impl DefCollector<'_> {
let mut unresolved_macros = mem::take(&mut self.unresolved_macros); let mut unresolved_macros = mem::take(&mut self.unresolved_macros);
let pos = unresolved_macros.iter().position(|directive| { let pos = unresolved_macros.iter().position(|directive| {
if let MacroDirectiveKind::Attr { ast_id, mod_item, attr, tree } = &directive.kind { if let MacroDirectiveKind::Attr { ast_id, mod_item, attr, tree } = &directive.kind {
self.def_map.diagnostics.push(DefDiagnostic::unresolved_proc_macro( self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call(
directive.module_id, directive.module_id,
MacroCallKind::Attr { MacroCallKind::Attr {
ast_id: ast_id.ast_id, ast_id: ast_id.ast_id,
@ -444,7 +444,7 @@ impl DefCollector<'_> {
invoc_attr_index: attr.id.ast_index, invoc_attr_index: attr.id.ast_index,
is_derive: false, is_derive: false,
}, },
None, attr.path().clone(),
)); ));
self.skip_attrs.insert(ast_id.ast_id.with_value(*mod_item), attr.id); self.skip_attrs.insert(ast_id.ast_id.with_value(*mod_item), attr.id);
@ -1218,10 +1218,6 @@ impl DefCollector<'_> {
return recollect_without(self); return recollect_without(self);
} }
if !self.db.enable_proc_attr_macros() {
return true;
}
// Not resolved to a derive helper or the derive attribute, so try to treat as a normal attribute. // Not resolved to a derive helper or the derive attribute, so try to treat as a normal attribute.
let call_id = attr_macro_as_call_id( let call_id = attr_macro_as_call_id(
self.db, self.db,
@ -1233,6 +1229,15 @@ impl DefCollector<'_> {
); );
let loc: MacroCallLoc = self.db.lookup_intern_macro_call(call_id); let loc: MacroCallLoc = self.db.lookup_intern_macro_call(call_id);
if !self.db.enable_proc_attr_macros() {
self.def_map.diagnostics.push(DefDiagnostic::unresolved_proc_macro(
directive.module_id,
loc.kind,
Some(loc.def.krate),
));
return recollect_without(self);
}
// Skip #[test]/#[bench] expansion, which would merely result in more memory usage // Skip #[test]/#[bench] expansion, which would merely result in more memory usage
// due to duplicating functions into macro expansions // due to duplicating functions into macro expansions
if matches!( if matches!(

View file

@ -20,6 +20,7 @@ hashbrown = { version = "0.12.1", features = [
"inline-more", "inline-more",
], default-features = false } ], default-features = false }
stdx = { path = "../stdx", version = "0.0.0" }
base-db = { path = "../base-db", version = "0.0.0" } base-db = { path = "../base-db", version = "0.0.0" }
cfg = { path = "../cfg", version = "0.0.0" } cfg = { path = "../cfg", version = "0.0.0" }
syntax = { path = "../syntax", version = "0.0.0" } syntax = { path = "../syntax", version = "0.0.0" }

View file

@ -1,6 +1,7 @@
//! Proc Macro Expander stub //! Proc Macro Expander stub
use base_db::{CrateId, ProcMacroExpansionError, ProcMacroId, ProcMacroKind}; use base_db::{CrateId, ProcMacroExpansionError, ProcMacroId, ProcMacroKind};
use stdx::never;
use crate::{db::AstDatabase, ExpandError, ExpandResult}; use crate::{db::AstDatabase, ExpandError, ExpandResult};
@ -36,18 +37,20 @@ impl ProcMacroExpander {
let krate_graph = db.crate_graph(); let krate_graph = db.crate_graph();
let proc_macros = match &krate_graph[self.krate].proc_macro { let proc_macros = match &krate_graph[self.krate].proc_macro {
Ok(proc_macros) => proc_macros, Ok(proc_macros) => proc_macros,
Err(e) => { Err(_) => {
return ExpandResult::only_err(ExpandError::Other( never!("Non-dummy expander even though there are no proc macros");
e.clone().into_boxed_str(), return ExpandResult::only_err(ExpandError::Other("Internal error".into()));
))
} }
}; };
let proc_macro = match proc_macros.get(id.0 as usize) { let proc_macro = match proc_macros.get(id.0 as usize) {
Some(proc_macro) => proc_macro, Some(proc_macro) => proc_macro,
None => { None => {
return ExpandResult::only_err(ExpandError::Other( never!(
"No proc-macro found.".into(), "Proc macro index out of bounds: the length is {} but the index is {}",
)) proc_macros.len(),
id.0
);
return ExpandResult::only_err(ExpandError::Other("Internal error".into()));
} }
}; };

View file

@ -69,6 +69,7 @@ pub struct UnresolvedImport {
#[derive(Debug, Clone, Eq, PartialEq)] #[derive(Debug, Clone, Eq, PartialEq)]
pub struct UnresolvedMacroCall { pub struct UnresolvedMacroCall {
pub macro_call: InFile<SyntaxNodePtr>, pub macro_call: InFile<SyntaxNodePtr>,
pub precise_location: Option<TextRange>,
pub path: ModPath, pub path: ModPath,
pub is_bang: bool, pub is_bang: bool,
} }
@ -95,6 +96,7 @@ pub struct UnresolvedProcMacro {
#[derive(Debug, Clone, Eq, PartialEq)] #[derive(Debug, Clone, Eq, PartialEq)]
pub struct MacroError { pub struct MacroError {
pub node: InFile<SyntaxNodePtr>, pub node: InFile<SyntaxNodePtr>,
pub precise_location: Option<TextRange>,
pub message: String, pub message: String,
} }

View file

@ -73,7 +73,7 @@ use rustc_hash::FxHashSet;
use stdx::{format_to, impl_from, never}; use stdx::{format_to, impl_from, never};
use syntax::{ use syntax::{
ast::{self, HasAttrs as _, HasDocComments, HasName}, ast::{self, HasAttrs as _, HasDocComments, HasName},
AstNode, AstPtr, SmolStr, SyntaxNodePtr, T, AstNode, AstPtr, SmolStr, SyntaxNodePtr, TextRange, T,
}; };
use crate::db::{DefDatabase, HirDatabase}; use crate::db::{DefDatabase, HirDatabase};
@ -628,67 +628,7 @@ fn emit_def_diagnostic(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, diag:
} }
DefDiagnosticKind::UnresolvedProcMacro { ast, krate } => { DefDiagnosticKind::UnresolvedProcMacro { ast, krate } => {
let (node, precise_location, macro_name, kind) = match ast { let (node, precise_location, macro_name, kind) = precise_macro_call_location(ast, db);
MacroCallKind::FnLike { ast_id, .. } => {
let node = ast_id.to_node(db.upcast());
(
ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node))),
node.path().map(|it| it.syntax().text_range()),
node.path().and_then(|it| it.segment()).map(|it| it.to_string()),
MacroKind::ProcMacro,
)
}
MacroCallKind::Derive { ast_id, derive_attr_index, derive_index } => {
let node = ast_id.to_node(db.upcast());
// Compute the precise location of the macro name's token in the derive
// list.
let token = (|| {
let derive_attr = node
.doc_comments_and_attrs()
.nth(*derive_attr_index as usize)
.and_then(Either::left)?;
let token_tree = derive_attr.meta()?.token_tree()?;
let group_by = token_tree
.syntax()
.children_with_tokens()
.filter_map(|elem| match elem {
syntax::NodeOrToken::Token(tok) => Some(tok),
_ => None,
})
.group_by(|t| t.kind() == T![,]);
let (_, mut group) = group_by
.into_iter()
.filter(|&(comma, _)| !comma)
.nth(*derive_index as usize)?;
group.find(|t| t.kind() == T![ident])
})();
(
ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node))),
token.as_ref().map(|tok| tok.text_range()),
token.as_ref().map(ToString::to_string),
MacroKind::Derive,
)
}
MacroCallKind::Attr { ast_id, invoc_attr_index, .. } => {
let node = ast_id.to_node(db.upcast());
let attr = node
.doc_comments_and_attrs()
.nth((*invoc_attr_index) as usize)
.and_then(Either::left)
.unwrap_or_else(|| panic!("cannot find attribute #{}", invoc_attr_index));
(
ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&attr))),
Some(attr.syntax().text_range()),
attr.path()
.and_then(|path| path.segment())
.and_then(|seg| seg.name_ref())
.as_ref()
.map(ToString::to_string),
MacroKind::Attr,
)
}
};
acc.push( acc.push(
UnresolvedProcMacro { node, precise_location, macro_name, kind, krate: *krate } UnresolvedProcMacro { node, precise_location, macro_name, kind, krate: *krate }
.into(), .into(),
@ -696,10 +636,11 @@ fn emit_def_diagnostic(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, diag:
} }
DefDiagnosticKind::UnresolvedMacroCall { ast, path } => { DefDiagnosticKind::UnresolvedMacroCall { ast, path } => {
let node = ast.to_node(db.upcast()); let (node, precise_location, _, _) = precise_macro_call_location(ast, db);
acc.push( acc.push(
UnresolvedMacroCall { UnresolvedMacroCall {
macro_call: InFile::new(node.file_id, SyntaxNodePtr::new(&node.value)), macro_call: node,
precise_location,
path: path.clone(), path: path.clone(),
is_bang: matches!(ast, MacroCallKind::FnLike { .. }), is_bang: matches!(ast, MacroCallKind::FnLike { .. }),
} }
@ -708,23 +649,8 @@ fn emit_def_diagnostic(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, diag:
} }
DefDiagnosticKind::MacroError { ast, message } => { DefDiagnosticKind::MacroError { ast, message } => {
let node = match ast { let (node, precise_location, _, _) = precise_macro_call_location(ast, db);
MacroCallKind::FnLike { ast_id, .. } => { acc.push(MacroError { node, precise_location, message: message.clone() }.into());
let node = ast_id.to_node(db.upcast());
ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node)))
}
MacroCallKind::Derive { ast_id, .. } => {
// FIXME: point to the attribute instead, this creates very large diagnostics
let node = ast_id.to_node(db.upcast());
ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node)))
}
MacroCallKind::Attr { ast_id, .. } => {
// FIXME: point to the attribute instead, this creates very large diagnostics
let node = ast_id.to_node(db.upcast());
ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node)))
}
};
acc.push(MacroError { node, message: message.clone() }.into());
} }
DefDiagnosticKind::UnimplementedBuiltinMacro { ast } => { DefDiagnosticKind::UnimplementedBuiltinMacro { ast } => {
@ -771,6 +697,78 @@ fn emit_def_diagnostic(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, diag:
} }
} }
fn precise_macro_call_location(
ast: &MacroCallKind,
db: &dyn HirDatabase,
) -> (InFile<SyntaxNodePtr>, Option<TextRange>, Option<String>, MacroKind) {
// FIXME: maaybe we actually want slightly different ranges for the different macro diagnostics
// - e.g. the full attribute for macro errors, but only the name for name resolution
match ast {
MacroCallKind::FnLike { ast_id, .. } => {
let node = ast_id.to_node(db.upcast());
(
ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node))),
node.path()
.and_then(|it| it.segment())
.and_then(|it| it.name_ref())
.map(|it| it.syntax().text_range()),
node.path().and_then(|it| it.segment()).map(|it| it.to_string()),
MacroKind::ProcMacro,
)
}
MacroCallKind::Derive { ast_id, derive_attr_index, derive_index } => {
let node = ast_id.to_node(db.upcast());
// Compute the precise location of the macro name's token in the derive
// list.
let token = (|| {
let derive_attr = node
.doc_comments_and_attrs()
.nth(*derive_attr_index as usize)
.and_then(Either::left)?;
let token_tree = derive_attr.meta()?.token_tree()?;
let group_by = token_tree
.syntax()
.children_with_tokens()
.filter_map(|elem| match elem {
syntax::NodeOrToken::Token(tok) => Some(tok),
_ => None,
})
.group_by(|t| t.kind() == T![,]);
let (_, mut group) = group_by
.into_iter()
.filter(|&(comma, _)| !comma)
.nth(*derive_index as usize)?;
group.find(|t| t.kind() == T![ident])
})();
(
ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node))),
token.as_ref().map(|tok| tok.text_range()),
token.as_ref().map(ToString::to_string),
MacroKind::Derive,
)
}
MacroCallKind::Attr { ast_id, invoc_attr_index, .. } => {
let node = ast_id.to_node(db.upcast());
let attr = node
.doc_comments_and_attrs()
.nth((*invoc_attr_index) as usize)
.and_then(Either::left)
.unwrap_or_else(|| panic!("cannot find attribute #{}", invoc_attr_index));
(
ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&attr))),
Some(attr.syntax().text_range()),
attr.path()
.and_then(|path| path.segment())
.and_then(|seg| seg.name_ref())
.as_ref()
.map(ToString::to_string),
MacroKind::Attr,
)
}
}
}
impl HasVisibility for Module { impl HasVisibility for Module {
fn visibility(&self, db: &dyn HirDatabase) -> Visibility { fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
let def_map = self.id.def_map(db.upcast()); let def_map = self.id.def_map(db.upcast());
@ -1156,6 +1154,7 @@ impl DefWithBody {
BodyDiagnostic::MacroError { node, message } => acc.push( BodyDiagnostic::MacroError { node, message } => acc.push(
MacroError { MacroError {
node: node.clone().map(|it| it.into()), node: node.clone().map(|it| it.into()),
precise_location: None,
message: message.to_string(), message: message.to_string(),
} }
.into(), .into(),
@ -1173,6 +1172,7 @@ impl DefWithBody {
BodyDiagnostic::UnresolvedMacroCall { node, path } => acc.push( BodyDiagnostic::UnresolvedMacroCall { node, path } => acc.push(
UnresolvedMacroCall { UnresolvedMacroCall {
macro_call: node.clone().map(|ast_ptr| ast_ptr.into()), macro_call: node.clone().map(|ast_ptr| ast_ptr.into()),
precise_location: None,
path: path.clone(), path: path.clone(),
is_bang: true, is_bang: true,
} }

View file

@ -4,12 +4,12 @@ use crate::{Diagnostic, DiagnosticsContext};
// //
// This diagnostic is shown for macro expansion errors. // This diagnostic is shown for macro expansion errors.
pub(crate) fn macro_error(ctx: &DiagnosticsContext<'_>, d: &hir::MacroError) -> Diagnostic { pub(crate) fn macro_error(ctx: &DiagnosticsContext<'_>, d: &hir::MacroError) -> Diagnostic {
Diagnostic::new( // Use more accurate position if available.
"macro-error", let display_range = d
d.message.clone(), .precise_location
ctx.sema.diagnostics_display_range(d.node.clone()).range, .unwrap_or_else(|| ctx.sema.diagnostics_display_range(d.node.clone()).range);
)
.experimental() Diagnostic::new("macro-error", d.message.clone(), display_range).experimental()
} }
#[cfg(test)] #[cfg(test)]
@ -30,10 +30,10 @@ macro_rules! include { () => {} }
macro_rules! compile_error { () => {} } macro_rules! compile_error { () => {} }
include!("doesntexist"); include!("doesntexist");
//^^^^^^^^^^^^^^^^^^^^^^^^ error: failed to load file `doesntexist` //^^^^^^^ error: failed to load file `doesntexist`
compile_error!("compile_error macro works"); compile_error!("compile_error macro works");
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: compile_error macro works //^^^^^^^^^^^^^ error: compile_error macro works
"#, "#,
); );
} }
@ -111,7 +111,7 @@ macro_rules! env { () => {} }
macro_rules! concat { () => {} } macro_rules! concat { () => {} }
include!(concat!(env!("OUT_DIR"), "/out.rs")); include!(concat!(env!("OUT_DIR"), "/out.rs"));
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `OUT_DIR` not set, enable "build scripts" to fix //^^^^^^^ error: `OUT_DIR` not set, enable "build scripts" to fix
"#, "#,
); );
} }
@ -153,23 +153,23 @@ fn main() {
// Test a handful of built-in (eager) macros: // Test a handful of built-in (eager) macros:
include!(invalid); include!(invalid);
//^^^^^^^^^^^^^^^^^ error: could not convert tokens //^^^^^^^ error: could not convert tokens
include!("does not exist"); include!("does not exist");
//^^^^^^^^^^^^^^^^^^^^^^^^^^ error: failed to load file `does not exist` //^^^^^^^ error: failed to load file `does not exist`
env!(invalid); env!(invalid);
//^^^^^^^^^^^^^ error: could not convert tokens //^^^ error: could not convert tokens
env!("OUT_DIR"); env!("OUT_DIR");
//^^^^^^^^^^^^^^^ error: `OUT_DIR` not set, enable "build scripts" to fix //^^^ error: `OUT_DIR` not set, enable "build scripts" to fix
compile_error!("compile_error works"); compile_error!("compile_error works");
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: compile_error works //^^^^^^^^^^^^^ error: compile_error works
// Lazy: // Lazy:
format_args!(); format_args!();
//^^^^^^^^^^^^^^ error: no rule matches input tokens //^^^^^^^^^^^ error: no rule matches input tokens
} }
"#, "#,
); );
@ -186,7 +186,7 @@ fn f() {
m!(); m!();
m!(hi); m!(hi);
//^^^^^^ error: leftover tokens //^ error: leftover tokens
} }
"#, "#,
); );

View file

@ -1,6 +1,3 @@
use hir::{db::AstDatabase, InFile};
use syntax::{ast, AstNode, SyntaxNodePtr};
use crate::{Diagnostic, DiagnosticsContext}; use crate::{Diagnostic, DiagnosticsContext};
// Diagnostic: unresolved-macro-call // Diagnostic: unresolved-macro-call
@ -11,25 +8,16 @@ pub(crate) fn unresolved_macro_call(
ctx: &DiagnosticsContext<'_>, ctx: &DiagnosticsContext<'_>,
d: &hir::UnresolvedMacroCall, d: &hir::UnresolvedMacroCall,
) -> Diagnostic { ) -> Diagnostic {
let last_path_segment = ctx.sema.db.parse_or_expand(d.macro_call.file_id).and_then(|root| { // Use more accurate position if available.
let node = d.macro_call.value.to_node(&root); let display_range = d
if let Some(macro_call) = ast::MacroCall::cast(node) { .precise_location
macro_call .unwrap_or_else(|| ctx.sema.diagnostics_display_range(d.macro_call.clone()).range);
.path()
.and_then(|it| it.segment())
.and_then(|it| it.name_ref())
.map(|it| InFile::new(d.macro_call.file_id, SyntaxNodePtr::new(it.syntax())))
} else {
None
}
});
let diagnostics = last_path_segment.unwrap_or_else(|| d.macro_call.clone().map(|it| it.into()));
let bang = if d.is_bang { "!" } else { "" }; let bang = if d.is_bang { "!" } else { "" };
Diagnostic::new( Diagnostic::new(
"unresolved-macro-call", "unresolved-macro-call",
format!("unresolved macro `{}{}`", d.path, bang), format!("unresolved macro `{}{}`", d.path, bang),
ctx.sema.diagnostics_display_range(diagnostics).range, display_range,
) )
.experimental() .experimental()
} }

View file

@ -172,8 +172,8 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Ok( proc_macro: Err(
[], "no build data",
), ),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
@ -247,8 +247,8 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Ok( proc_macro: Err(
[], "no build data",
), ),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
@ -312,8 +312,8 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
}, },
}, },
dependencies: [], dependencies: [],
proc_macro: Ok( proc_macro: Err(
[], "no build data",
), ),
origin: CratesIo { origin: CratesIo {
repo: Some( repo: Some(
@ -389,8 +389,8 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Ok( proc_macro: Err(
[], "no build data",
), ),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
@ -464,8 +464,8 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Ok( proc_macro: Err(
[], "no build data",
), ),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
@ -554,8 +554,8 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Ok( proc_macro: Err(
[], "no build data",
), ),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
@ -631,8 +631,8 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Ok( proc_macro: Err(
[], "no build data",
), ),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
@ -696,8 +696,8 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
}, },
}, },
dependencies: [], dependencies: [],
proc_macro: Ok( proc_macro: Err(
[], "no build data",
), ),
origin: CratesIo { origin: CratesIo {
repo: Some( repo: Some(
@ -775,8 +775,8 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Ok( proc_macro: Err(
[], "no build data",
), ),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
@ -852,8 +852,8 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Ok( proc_macro: Err(
[], "no build data",
), ),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
@ -933,8 +933,8 @@ fn cargo_hello_world_project_model() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Ok( proc_macro: Err(
[], "no build data",
), ),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
@ -1010,8 +1010,8 @@ fn cargo_hello_world_project_model() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Ok( proc_macro: Err(
[], "no build data",
), ),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
@ -1075,8 +1075,8 @@ fn cargo_hello_world_project_model() {
}, },
}, },
dependencies: [], dependencies: [],
proc_macro: Ok( proc_macro: Err(
[], "no build data",
), ),
origin: CratesIo { origin: CratesIo {
repo: Some( repo: Some(
@ -1154,8 +1154,8 @@ fn cargo_hello_world_project_model() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Ok( proc_macro: Err(
[], "no build data",
), ),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
@ -1231,8 +1231,8 @@ fn cargo_hello_world_project_model() {
prelude: true, prelude: true,
}, },
], ],
proc_macro: Ok( proc_macro: Err(
[], "no build data",
), ),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,
@ -1505,8 +1505,8 @@ fn rust_project_hello_world_project_model() {
prelude: false, prelude: false,
}, },
], ],
proc_macro: Ok( proc_macro: Err(
[], "no proc macro dylib present",
), ),
origin: CratesIo { origin: CratesIo {
repo: None, repo: None,

View file

@ -459,7 +459,7 @@ fn project_json_to_crate_graph(
krate.display_name.as_ref().map(|it| it.canonical_name()).unwrap_or(""), krate.display_name.as_ref().map(|it| it.canonical_name()).unwrap_or(""),
&it, &it,
), ),
None => Ok(Vec::new()), None => Err("no proc macro dylib present".into()),
}; };
let target_cfgs = match krate.target.as_deref() { let target_cfgs = match krate.target.as_deref() {
@ -870,9 +870,10 @@ fn add_target_crate_root(
} }
} }
let proc_macro = match build_data.as_ref().and_then(|it| it.proc_macro_dylib_path.as_ref()) { let proc_macro = match build_data.as_ref().map(|it| it.proc_macro_dylib_path.as_ref()) {
Some(it) => load_proc_macro(it), Some(Some(it)) => load_proc_macro(it),
None => Ok(Vec::new()), Some(None) => Err("no proc macro dylib present".into()),
None => Err("no build data".into()),
}; };
let display_name = CrateDisplayName::from_canonical_name(cargo_name.to_string()); let display_name = CrateDisplayName::from_canonical_name(cargo_name.to_string());