Supress some lookup errors if a module contains compile_error!
The problem is that when a macro expand to `compile_error!` because its input is malformed, the actual error message from the `compile_error!` might be hidden in a long list of other messages about using items that should have otherwise been generated by the macro. So suppress error about missing items in that module. Fixes issue 68838
This commit is contained in:
parent
621d76794c
commit
f3e73dced1
6 changed files with 101 additions and 1 deletions
|
|
@ -22,6 +22,7 @@ pub(crate) fn expand_compile_error<'cx>(
|
|||
#[expect(rustc::diagnostic_outside_of_impl, reason = "diagnostic message is specified by user")]
|
||||
#[expect(rustc::untranslatable_diagnostic, reason = "diagnostic message is specified by user")]
|
||||
let guar = cx.dcx().span_err(sp, var.to_string());
|
||||
cx.resolver.mark_scope_with_compile_error(cx.current_expansion.lint_node_id);
|
||||
|
||||
ExpandResult::Ready(DummyResult::any(sp, guar))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1173,6 +1173,10 @@ pub trait ResolverExpand {
|
|||
/// Record the name of an opaque `Ty::ImplTrait` pre-expansion so that it can be used
|
||||
/// to generate an item name later that does not reference placeholder macros.
|
||||
fn insert_impl_trait_name(&mut self, id: NodeId, name: Symbol);
|
||||
|
||||
/// Mark the scope as having a compile error so that error for lookup in this scope
|
||||
/// should be suppressed
|
||||
fn mark_scope_with_compile_error(&mut self, parent_node: NodeId);
|
||||
}
|
||||
|
||||
pub trait LintStoreExpand {
|
||||
|
|
|
|||
|
|
@ -1711,7 +1711,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
diag_metadata: Option<&DiagMetadata<'_>>,
|
||||
) -> PathResult<'ra> {
|
||||
let mut module = None;
|
||||
let mut module_had_parse_errors = false;
|
||||
let mut module_had_parse_errors = !self.mods_with_parse_errors.is_empty()
|
||||
&& self.mods_with_parse_errors.contains(&parent_scope.module.nearest_parent_mod());
|
||||
let mut allow_super = true;
|
||||
let mut second_binding = None;
|
||||
|
||||
|
|
|
|||
|
|
@ -166,6 +166,14 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
|
|||
self.invocation_parents[&id].parent_def
|
||||
}
|
||||
|
||||
fn mark_scope_with_compile_error(&mut self, id: NodeId) {
|
||||
if let Some(id) = self.opt_local_def_id(id)
|
||||
&& self.tcx.def_kind(id).is_module_like()
|
||||
{
|
||||
self.mods_with_parse_errors.insert(id.to_def_id());
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_dollar_crates(&self) {
|
||||
hygiene::update_dollar_crate_names(|ctxt| {
|
||||
let ident = Ident::new(kw::DollarCrate, DUMMY_SP.with_ctxt(ctxt));
|
||||
|
|
|
|||
40
tests/ui/macros/compile_error_macro-suppress-errors.rs
Normal file
40
tests/ui/macros/compile_error_macro-suppress-errors.rs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
pub mod some_module {
|
||||
compile_error!("Error in a module"); //~ ERROR: Error in a module
|
||||
|
||||
fn abc() -> Hello {
|
||||
let _: self::SomeType = self::Hello::new();
|
||||
let _: SomeType = Hello::new();
|
||||
}
|
||||
|
||||
mod inner_module {
|
||||
use super::Hello;
|
||||
use crate::another_module::NotExist; //~ ERROR: unresolved import `crate::another_module::NotExist`
|
||||
use crate::some_module::World;
|
||||
struct Foo {
|
||||
bar: crate::some_module::Xyz,
|
||||
error: self::MissingType, //~ ERROR: cannot find type `MissingType` in module `self`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod another_module {
|
||||
use crate::some_module::NotExist;
|
||||
fn error_in_this_function() {
|
||||
compile_error!("Error in a function"); //~ ERROR: Error in a function
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// these errors are suppressed because of the compile_error! macro
|
||||
|
||||
let _ = some_module::some_function();
|
||||
let _: some_module::SomeType = some_module::Hello::new();
|
||||
|
||||
// these errors are not suppressed
|
||||
|
||||
let _ = another_module::some_function();
|
||||
//~^ ERROR: cannot find function `some_function` in module `another_module`
|
||||
let _: another_module::SomeType = another_module::Hello::new();
|
||||
//~^ ERROR: cannot find type `SomeType` in module `another_module`
|
||||
//~^^ ERROR: failed to resolve: could not find `Hello` in `another_module`
|
||||
}
|
||||
46
tests/ui/macros/compile_error_macro-suppress-errors.stderr
Normal file
46
tests/ui/macros/compile_error_macro-suppress-errors.stderr
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
error: Error in a module
|
||||
--> $DIR/compile_error_macro-suppress-errors.rs:2:5
|
||||
|
|
||||
LL | compile_error!("Error in a module");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: Error in a function
|
||||
--> $DIR/compile_error_macro-suppress-errors.rs:23:9
|
||||
|
|
||||
LL | compile_error!("Error in a function");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0432]: unresolved import `crate::another_module::NotExist`
|
||||
--> $DIR/compile_error_macro-suppress-errors.rs:11:13
|
||||
|
|
||||
LL | use crate::another_module::NotExist;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `NotExist` in `another_module`
|
||||
|
||||
error[E0433]: failed to resolve: could not find `Hello` in `another_module`
|
||||
--> $DIR/compile_error_macro-suppress-errors.rs:37:55
|
||||
|
|
||||
LL | let _: another_module::SomeType = another_module::Hello::new();
|
||||
| ^^^^^ could not find `Hello` in `another_module`
|
||||
|
||||
error[E0425]: cannot find type `MissingType` in module `self`
|
||||
--> $DIR/compile_error_macro-suppress-errors.rs:15:26
|
||||
|
|
||||
LL | error: self::MissingType,
|
||||
| ^^^^^^^^^^^ not found in `self`
|
||||
|
||||
error[E0425]: cannot find function `some_function` in module `another_module`
|
||||
--> $DIR/compile_error_macro-suppress-errors.rs:35:29
|
||||
|
|
||||
LL | let _ = another_module::some_function();
|
||||
| ^^^^^^^^^^^^^ not found in `another_module`
|
||||
|
||||
error[E0425]: cannot find type `SomeType` in module `another_module`
|
||||
--> $DIR/compile_error_macro-suppress-errors.rs:37:28
|
||||
|
|
||||
LL | let _: another_module::SomeType = another_module::Hello::new();
|
||||
| ^^^^^^^^ not found in `another_module`
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0425, E0432, E0433.
|
||||
For more information about an error, try `rustc --explain E0425`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue