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

View file

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