Skip to content

Commit

Permalink
Rollup merge of rust-lang#88232 - m-ou-se:macro-name-imported-but-not…
Browse files Browse the repository at this point in the history
…-macro, r=estebank

Add notes to macro-not-found diagnostics to point out how things with the same name were not a match.

This adds notes like:
```
error: cannot find derive macro `Serialize` in this scope
  --> $DIR/issue-88206.rs:22:10
   |
LL | #[derive(Serialize)]
   |          ^^^^^^^^^
   |
note: `Serialize` is imported here, but it is not a derive macro
  --> $DIR/issue-88206.rs:17:11
   |
LL | use hey::{Serialize, Deserialize};
   |           ^^^^^^^^^
```

Fixes rust-lang#88206

Includes rust-lang#88229

r? `@estebank`
  • Loading branch information
m-ou-se authored Aug 23, 2021
2 parents 5cf025f + 908ce2f commit c31e02a
Show file tree
Hide file tree
Showing 8 changed files with 250 additions and 1 deletion.
52 changes: 52 additions & 0 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -956,9 +956,61 @@ impl<'a> Resolver<'a> {
if macro_kind == MacroKind::Derive && (ident.name == sym::Send || ident.name == sym::Sync) {
let msg = format!("unsafe traits like `{}` should be implemented explicitly", ident);
err.span_note(ident.span, &msg);
return;
}
if self.macro_names.contains(&ident.normalize_to_macros_2_0()) {
err.help("have you added the `#[macro_use]` on the module/import?");
return;
}
for ns in [Namespace::MacroNS, Namespace::TypeNS, Namespace::ValueNS] {
if let Ok(binding) = self.early_resolve_ident_in_lexical_scope(
ident,
ScopeSet::All(ns, false),
&parent_scope,
false,
false,
ident.span,
) {
let desc = match binding.res() {
Res::Def(DefKind::Macro(MacroKind::Bang), _) => {
"a function-like macro".to_string()
}
Res::Def(DefKind::Macro(MacroKind::Attr), _) | Res::NonMacroAttr(..) => {
format!("an attribute: `#[{}]`", ident)
}
Res::Def(DefKind::Macro(MacroKind::Derive), _) => {
format!("a derive macro: `#[derive({})]`", ident)
}
Res::ToolMod => {
// Don't confuse the user with tool modules.
continue;
}
Res::Def(DefKind::Trait, _) if macro_kind == MacroKind::Derive => {
"only a trait, without a derive macro".to_string()
}
res => format!(
"{} {}, not {} {}",
res.article(),
res.descr(),
macro_kind.article(),
macro_kind.descr_expected(),
),
};
if let crate::NameBindingKind::Import { import, .. } = binding.kind {
if !import.span.is_dummy() {
err.span_note(
import.span,
&format!("`{}` is imported here, but it is {}", ident, desc),
);
// Silence the 'unused import' warning we might get,
// since this diagnostic already covers that import.
self.record_use(ident, binding, false);
return;
}
}
err.note(&format!("`{}` is in scope, but it is {}", ident, desc));
return;
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/issues/issue-11692-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ error: cannot find macro `test` in this scope
|
LL | concat!(test!());
| ^^^^
|
= note: `test` is in scope, but it is an attribute: `#[test]`

error: aborting due to previous error

66 changes: 66 additions & 0 deletions src/test/ui/macros/issue-88206.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// compile-flags: -Z deduplicate-diagnostics=yes

#![warn(unused_imports)]

use std::str::*;
//~^ NOTE `from_utf8` is imported here, but it is a function
//~| NOTE `from_utf8_mut` is imported here, but it is a function
//~| NOTE `from_utf8_unchecked` is imported here, but it is a function

mod hey {
pub trait Serialize {}
pub trait Deserialize {}

pub struct X(i32);
}

use hey::{Serialize, Deserialize, X};
//~^ NOTE `Serialize` is imported here, but it is only a trait, without a derive macro
//~| NOTE `Deserialize` is imported here, but it is a trait
//~| NOTE `X` is imported here, but it is a struct

#[derive(Serialize)]
//~^ ERROR cannot find derive macro `Serialize`
struct A;

#[derive(from_utf8_mut)]
//~^ ERROR cannot find derive macro `from_utf8_mut`
struct B;

#[derive(println)]
//~^ ERROR cannot find derive macro `println`
//~| NOTE `println` is in scope, but it is a function-like macro
struct C;

#[Deserialize]
//~^ ERROR cannot find attribute `Deserialize`
struct D;

#[from_utf8_unchecked]
//~^ ERROR cannot find attribute `from_utf8_unchecked`
struct E;

#[println]
//~^ ERROR cannot find attribute `println`
//~| NOTE `println` is in scope, but it is a function-like macro
struct F;

fn main() {
from_utf8!();
//~^ ERROR cannot find macro `from_utf8`

Box!();
//~^ ERROR cannot find macro `Box`
//~| NOTE `Box` is in scope, but it is a struct

Copy!();
//~^ ERROR cannot find macro `Copy`
//~| NOTE `Copy` is in scope, but it is a derive macro

test!();
//~^ ERROR cannot find macro `test`
//~| NOTE `test` is in scope, but it is an attribute

X!();
//~^ ERROR cannot find macro `X`
}
114 changes: 114 additions & 0 deletions src/test/ui/macros/issue-88206.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
error: cannot find macro `X` in this scope
--> $DIR/issue-88206.rs:64:5
|
LL | X!();
| ^
|
note: `X` is imported here, but it is a struct, not a macro
--> $DIR/issue-88206.rs:17:35
|
LL | use hey::{Serialize, Deserialize, X};
| ^

error: cannot find macro `test` in this scope
--> $DIR/issue-88206.rs:60:5
|
LL | test!();
| ^^^^
|
= note: `test` is in scope, but it is an attribute: `#[test]`

error: cannot find macro `Copy` in this scope
--> $DIR/issue-88206.rs:56:5
|
LL | Copy!();
| ^^^^
|
= note: `Copy` is in scope, but it is a derive macro: `#[derive(Copy)]`

error: cannot find macro `Box` in this scope
--> $DIR/issue-88206.rs:52:5
|
LL | Box!();
| ^^^
|
= note: `Box` is in scope, but it is a struct, not a macro

error: cannot find macro `from_utf8` in this scope
--> $DIR/issue-88206.rs:49:5
|
LL | from_utf8!();
| ^^^^^^^^^
|
note: `from_utf8` is imported here, but it is a function, not a macro
--> $DIR/issue-88206.rs:5:5
|
LL | use std::str::*;
| ^^^^^^^^^^^

error: cannot find attribute `println` in this scope
--> $DIR/issue-88206.rs:43:3
|
LL | #[println]
| ^^^^^^^
|
= note: `println` is in scope, but it is a function-like macro

error: cannot find attribute `from_utf8_unchecked` in this scope
--> $DIR/issue-88206.rs:39:3
|
LL | #[from_utf8_unchecked]
| ^^^^^^^^^^^^^^^^^^^
|
note: `from_utf8_unchecked` is imported here, but it is a function, not an attribute
--> $DIR/issue-88206.rs:5:5
|
LL | use std::str::*;
| ^^^^^^^^^^^

error: cannot find attribute `Deserialize` in this scope
--> $DIR/issue-88206.rs:35:3
|
LL | #[Deserialize]
| ^^^^^^^^^^^
|
note: `Deserialize` is imported here, but it is a trait, not an attribute
--> $DIR/issue-88206.rs:17:22
|
LL | use hey::{Serialize, Deserialize, X};
| ^^^^^^^^^^^

error: cannot find derive macro `println` in this scope
--> $DIR/issue-88206.rs:30:10
|
LL | #[derive(println)]
| ^^^^^^^
|
= note: `println` is in scope, but it is a function-like macro

error: cannot find derive macro `from_utf8_mut` in this scope
--> $DIR/issue-88206.rs:26:10
|
LL | #[derive(from_utf8_mut)]
| ^^^^^^^^^^^^^
|
note: `from_utf8_mut` is imported here, but it is a function, not a derive macro
--> $DIR/issue-88206.rs:5:5
|
LL | use std::str::*;
| ^^^^^^^^^^^

error: cannot find derive macro `Serialize` in this scope
--> $DIR/issue-88206.rs:22:10
|
LL | #[derive(Serialize)]
| ^^^^^^^^^
|
note: `Serialize` is imported here, but it is only a trait, without a derive macro
--> $DIR/issue-88206.rs:17:11
|
LL | use hey::{Serialize, Deserialize, X};
| ^^^^^^^^^

error: aborting due to 11 previous errors

1 change: 1 addition & 0 deletions src/test/ui/macros/issue-88228.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ struct A;

#[derive(println)]
//~^ ERROR cannot find derive macro `println`
//~|`println` is in scope, but it is a function-like macro
struct B;

fn main() {
Expand Down
4 changes: 3 additions & 1 deletion src/test/ui/macros/issue-88228.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: cannot find macro `bla` in this scope
--> $DIR/issue-88228.rs:19:5
--> $DIR/issue-88228.rs:20:5
|
LL | bla!();
| ^^^
Expand All @@ -12,6 +12,8 @@ error: cannot find derive macro `println` in this scope
|
LL | #[derive(println)]
| ^^^^^^^
|
= note: `println` is in scope, but it is a function-like macro

error: cannot find derive macro `Bla` in this scope
--> $DIR/issue-88228.rs:9:10
Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/macros/macro-path-prelude-fail-3.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ LL | inline!();
|
LL | macro_rules! line {
| ----------------- similarly named macro `line` defined here
|
= note: `inline` is in scope, but it is an attribute: `#[inline]`

error: aborting due to previous error

10 changes: 10 additions & 0 deletions src/test/ui/proc-macro/macro-namespace-reserved-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -93,30 +93,40 @@ error: cannot find macro `my_macro_attr` in this scope
|
LL | my_macro_attr!();
| ^^^^^^^^^^^^^
|
= note: `my_macro_attr` is in scope, but it is an attribute: `#[my_macro_attr]`

error: cannot find macro `MyTrait` in this scope
--> $DIR/macro-namespace-reserved-2.rs:33:5
|
LL | MyTrait!();
| ^^^^^^^
|
= note: `MyTrait` is in scope, but it is a derive macro: `#[derive(MyTrait)]`

error: cannot find attribute `my_macro` in this scope
--> $DIR/macro-namespace-reserved-2.rs:38:3
|
LL | #[my_macro]
| ^^^^^^^^
|
= note: `my_macro` is in scope, but it is a function-like macro

error: cannot find derive macro `my_macro` in this scope
--> $DIR/macro-namespace-reserved-2.rs:48:10
|
LL | #[derive(my_macro)]
| ^^^^^^^^
|
= note: `my_macro` is in scope, but it is a function-like macro

error: cannot find derive macro `my_macro` in this scope
--> $DIR/macro-namespace-reserved-2.rs:48:10
|
LL | #[derive(my_macro)]
| ^^^^^^^^
|
= note: `my_macro` is in scope, but it is a function-like macro

error: aborting due to 20 previous errors

0 comments on commit c31e02a

Please sign in to comment.