From 017747fa5afb1e5396582498303c8437792966d7 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Wed, 19 Jan 2022 02:27:15 +0000 Subject: [PATCH] Only suggest adding `!` to expressions that can be macro invocation --- compiler/rustc_resolve/src/late.rs | 4 ++ .../rustc_resolve/src/late/diagnostics.rs | 11 ++++- .../hygiene/rustc-macro-transparency.stderr | 28 ++++-------- src/test/ui/resolve/resolve-hint-macro.fixed | 11 +++++ src/test/ui/resolve/resolve-hint-macro.rs | 7 +++ src/test/ui/resolve/resolve-hint-macro.stderr | 45 +++++++++++++++++-- 6 files changed, 82 insertions(+), 24 deletions(-) create mode 100644 src/test/ui/resolve/resolve-hint-macro.fixed diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index ccaaa2eaf46..2c678e71ae1 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2517,6 +2517,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { self.visit_expr(elem); self.resolve_anon_const(ct, IsRepeatExpr::Yes); } + ExprKind::Index(ref elem, ref idx) => { + self.resolve_expr(elem, Some(expr)); + self.visit_expr(idx); + } _ => { visit::walk_expr(self, expr); } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 4cd1b34bedc..7b4fe6f0e07 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -970,7 +970,13 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { }; match (res, source) { - (Res::Def(DefKind::Macro(MacroKind::Bang), _), _) => { + ( + Res::Def(DefKind::Macro(MacroKind::Bang), _), + PathSource::Expr(Some(Expr { + kind: ExprKind::Index(..) | ExprKind::Call(..), .. + })) + | PathSource::Struct, + ) => { err.span_label(span, fallback_label); err.span_suggestion_verbose( span.shrink_to_hi(), @@ -982,6 +988,9 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.note("if you want the `try` keyword, you need Rust 2018 or later"); } } + (Res::Def(DefKind::Macro(MacroKind::Bang), _), _) => { + err.span_label(span, fallback_label); + } (Res::Def(DefKind::TyAlias, def_id), PathSource::Trait(_)) => { err.span_label(span, "type aliases cannot be used as traits"); if self.r.session.is_nightly_build() { diff --git a/src/test/ui/hygiene/rustc-macro-transparency.stderr b/src/test/ui/hygiene/rustc-macro-transparency.stderr index e4c1c8ad293..17d05dd0963 100644 --- a/src/test/ui/hygiene/rustc-macro-transparency.stderr +++ b/src/test/ui/hygiene/rustc-macro-transparency.stderr @@ -11,16 +11,10 @@ LL | struct SemiTransparent; | ----------------------- similarly named unit struct `SemiTransparent` defined here ... LL | semitransparent; - | ^^^^^^^^^^^^^^^ not a value - | -help: use `!` to invoke the macro - | -LL | semitransparent!; - | + -help: a unit struct with a similar name exists - | -LL | SemiTransparent; - | ~~~~~~~~~~~~~~~ + | ^^^^^^^^^^^^^^^ + | | + | not a value + | help: a unit struct with a similar name exists: `SemiTransparent` error[E0423]: expected value, found macro `opaque` --> $DIR/rustc-macro-transparency.rs:30:5 @@ -29,16 +23,10 @@ LL | struct Opaque; | -------------- similarly named unit struct `Opaque` defined here ... LL | opaque; - | ^^^^^^ not a value - | -help: use `!` to invoke the macro - | -LL | opaque!; - | + -help: a unit struct with a similar name exists - | -LL | Opaque; - | ~~~~~~ + | ^^^^^^ + | | + | not a value + | help: a unit struct with a similar name exists (notice the capitalization): `Opaque` error: aborting due to 3 previous errors diff --git a/src/test/ui/resolve/resolve-hint-macro.fixed b/src/test/ui/resolve/resolve-hint-macro.fixed new file mode 100644 index 00000000000..54e01608498 --- /dev/null +++ b/src/test/ui/resolve/resolve-hint-macro.fixed @@ -0,0 +1,11 @@ +// run-rustfix +fn main() { + assert_eq!(1, 1); + //~^ ERROR expected function, found macro `assert_eq` + assert_eq! { 1, 1 }; + //~^ ERROR expected struct, variant or union type, found macro `assert_eq` + //~| ERROR expected identifier, found `1` + //~| ERROR expected identifier, found `1` + assert![true]; + //~^ ERROR expected value, found macro `assert` +} diff --git a/src/test/ui/resolve/resolve-hint-macro.rs b/src/test/ui/resolve/resolve-hint-macro.rs index 5532c8b90e3..f16e8c07553 100644 --- a/src/test/ui/resolve/resolve-hint-macro.rs +++ b/src/test/ui/resolve/resolve-hint-macro.rs @@ -1,4 +1,11 @@ +// run-rustfix fn main() { assert_eq(1, 1); //~^ ERROR expected function, found macro `assert_eq` + assert_eq { 1, 1 }; + //~^ ERROR expected struct, variant or union type, found macro `assert_eq` + //~| ERROR expected identifier, found `1` + //~| ERROR expected identifier, found `1` + assert[true]; + //~^ ERROR expected value, found macro `assert` } diff --git a/src/test/ui/resolve/resolve-hint-macro.stderr b/src/test/ui/resolve/resolve-hint-macro.stderr index 78d77678083..bc69ddd8ffe 100644 --- a/src/test/ui/resolve/resolve-hint-macro.stderr +++ b/src/test/ui/resolve/resolve-hint-macro.stderr @@ -1,5 +1,21 @@ +error: expected identifier, found `1` + --> $DIR/resolve-hint-macro.rs:5:17 + | +LL | assert_eq { 1, 1 }; + | --------- ^ expected identifier + | | + | while parsing this struct + +error: expected identifier, found `1` + --> $DIR/resolve-hint-macro.rs:5:20 + | +LL | assert_eq { 1, 1 }; + | --------- ^ expected identifier + | | + | while parsing this struct + error[E0423]: expected function, found macro `assert_eq` - --> $DIR/resolve-hint-macro.rs:2:5 + --> $DIR/resolve-hint-macro.rs:3:5 | LL | assert_eq(1, 1); | ^^^^^^^^^ not a function @@ -9,6 +25,29 @@ help: use `!` to invoke the macro LL | assert_eq!(1, 1); | + -error: aborting due to previous error +error[E0574]: expected struct, variant or union type, found macro `assert_eq` + --> $DIR/resolve-hint-macro.rs:5:5 + | +LL | assert_eq { 1, 1 }; + | ^^^^^^^^^ not a struct, variant or union type + | +help: use `!` to invoke the macro + | +LL | assert_eq! { 1, 1 }; + | + -For more information about this error, try `rustc --explain E0423`. +error[E0423]: expected value, found macro `assert` + --> $DIR/resolve-hint-macro.rs:9:5 + | +LL | assert[true]; + | ^^^^^^ not a value + | +help: use `!` to invoke the macro + | +LL | assert![true]; + | + + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0423, E0574. +For more information about an error, try `rustc --explain E0423`.