From 2ae90165534f18aa5020ae84f5e3768e99139069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 22 Sep 2019 11:27:55 -0700 Subject: [PATCH] Point at definition when misusing ADT When given `struct Foo(usize)` and using it as `Foo {}` or `Foo`, point at `Foo`'s definition in the error. --- src/librustc_resolve/late/diagnostics.rs | 22 +++++++----- .../ui/empty/empty-struct-braces-expr.stderr | 12 +++++++ .../ui/empty/empty-struct-braces-pat-1.stderr | 3 ++ .../ui/empty/empty-struct-braces-pat-2.stderr | 6 ++++ .../ui/empty/empty-struct-braces-pat-3.stderr | 6 ++++ .../ui/empty/empty-struct-tuple-pat.stderr | 7 ++-- src/test/ui/error-codes/E0423.stderr | 3 ++ src/test/ui/issues/issue-19086.stderr | 3 ++ src/test/ui/issues/issue-32004.stderr | 5 ++- src/test/ui/issues/issue-63983.stderr | 8 ++++- src/test/ui/namespace/namespace-mix.stderr | 3 ++ .../ui/parser/recover-from-bad-variant.stderr | 3 ++ src/test/ui/resolve/issue-18252.stderr | 3 ++ src/test/ui/resolve/issue-19452.stderr | 3 ++ src/test/ui/resolve/issue-39226.stderr | 3 ++ src/test/ui/resolve/issue-6702.stderr | 9 +++-- src/test/ui/resolve/privacy-enum-ctor.stderr | 36 ++++++++++++++----- .../ui/resolve/privacy-struct-ctor.stderr | 9 +++-- .../fn-or-tuple-struct-without-args.stderr | 3 ++ src/test/ui/suggestions/issue-61226.stderr | 3 ++ 20 files changed, 126 insertions(+), 24 deletions(-) diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index cd1689f21cc6e..c7385f8a99176 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -348,7 +348,7 @@ impl<'a> LateResolutionVisitor<'a, '_> { _ => false, }; - let mut bad_struct_syntax_suggestion = || { + let mut bad_struct_syntax_suggestion = |def_id: DefId| { let (followed_by_brace, closing_brace) = self.followed_by_brace(span); let mut suggested = false; match source { @@ -374,6 +374,9 @@ impl<'a> LateResolutionVisitor<'a, '_> { _ => {} } if !suggested { + if let Some(span) = self.r.definitions.opt_span(def_id) { + err.span_label(span, &format!("`{}` defined here", path_str)); + } err.span_label( span, format!("did you mean `{} {{ /* fields */ }}`?", path_str), @@ -437,18 +440,21 @@ impl<'a> LateResolutionVisitor<'a, '_> { ); } } else { - bad_struct_syntax_suggestion(); + bad_struct_syntax_suggestion(def_id); } } - (Res::Def(DefKind::Union, _), _) | - (Res::Def(DefKind::Variant, _), _) | - (Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _), _) if ns == ValueNS => { - bad_struct_syntax_suggestion(); + (Res::Def(DefKind::Union, def_id), _) | + (Res::Def(DefKind::Variant, def_id), _) | + (Res::Def(DefKind::Ctor(_, CtorKind::Fictive), def_id), _) if ns == ValueNS => { + bad_struct_syntax_suggestion(def_id); } - (Res::Def(DefKind::Ctor(_, CtorKind::Fn), _), _) if ns == ValueNS => { + (Res::Def(DefKind::Ctor(_, CtorKind::Fn), def_id), _) if ns == ValueNS => { + if let Some(span) = self.r.definitions.opt_span(def_id) { + err.span_label(span, &format!("`{}` defined here", path_str)); + } err.span_label( span, - format!("did you mean `{} ( /* fields */ )`?", path_str), + format!("did you mean `{}( /* fields */ )`?", path_str), ); } (Res::SelfTy(..), _) if ns == ValueNS => { diff --git a/src/test/ui/empty/empty-struct-braces-expr.stderr b/src/test/ui/empty/empty-struct-braces-expr.stderr index b9681db87b67e..9712157552716 100644 --- a/src/test/ui/empty/empty-struct-braces-expr.stderr +++ b/src/test/ui/empty/empty-struct-braces-expr.stderr @@ -1,6 +1,9 @@ error[E0423]: expected value, found struct `Empty1` --> $DIR/empty-struct-braces-expr.rs:15:14 | +LL | struct Empty1 {} + | ---------------- `Empty1` defined here +... LL | let e1 = Empty1; | ^^^^^^ | | @@ -10,6 +13,9 @@ LL | let e1 = Empty1; error[E0423]: expected function, found struct `Empty1` --> $DIR/empty-struct-braces-expr.rs:16:14 | +LL | struct Empty1 {} + | ---------------- `Empty1` defined here +... LL | let e1 = Empty1(); | ^^^^^^ | | @@ -19,12 +25,18 @@ LL | let e1 = Empty1(); error[E0423]: expected value, found struct variant `E::Empty3` --> $DIR/empty-struct-braces-expr.rs:17:14 | +LL | Empty3 {} + | --------- `E::Empty3` defined here +... LL | let e3 = E::Empty3; | ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`? error[E0423]: expected function, found struct variant `E::Empty3` --> $DIR/empty-struct-braces-expr.rs:18:14 | +LL | Empty3 {} + | --------- `E::Empty3` defined here +... LL | let e3 = E::Empty3(); | ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`? diff --git a/src/test/ui/empty/empty-struct-braces-pat-1.stderr b/src/test/ui/empty/empty-struct-braces-pat-1.stderr index 6c361c703440c..271e811a2fd65 100644 --- a/src/test/ui/empty/empty-struct-braces-pat-1.stderr +++ b/src/test/ui/empty/empty-struct-braces-pat-1.stderr @@ -1,6 +1,9 @@ error[E0532]: expected unit struct/variant or constant, found struct variant `E::Empty3` --> $DIR/empty-struct-braces-pat-1.rs:24:9 | +LL | Empty3 {} + | --------- `E::Empty3` defined here +... LL | E::Empty3 => () | ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`? diff --git a/src/test/ui/empty/empty-struct-braces-pat-2.stderr b/src/test/ui/empty/empty-struct-braces-pat-2.stderr index 12047b5880c3e..3352473788894 100644 --- a/src/test/ui/empty/empty-struct-braces-pat-2.stderr +++ b/src/test/ui/empty/empty-struct-braces-pat-2.stderr @@ -1,6 +1,9 @@ error[E0532]: expected tuple struct/variant, found struct `Empty1` --> $DIR/empty-struct-braces-pat-2.rs:15:9 | +LL | struct Empty1 {} + | ---------------- `Empty1` defined here +... LL | Empty1() => () | ^^^^^^ | | @@ -19,6 +22,9 @@ LL | XEmpty1() => () error[E0532]: expected tuple struct/variant, found struct `Empty1` --> $DIR/empty-struct-braces-pat-2.rs:21:9 | +LL | struct Empty1 {} + | ---------------- `Empty1` defined here +... LL | Empty1(..) => () | ^^^^^^ | | diff --git a/src/test/ui/empty/empty-struct-braces-pat-3.stderr b/src/test/ui/empty/empty-struct-braces-pat-3.stderr index af8731b5f0596..aefdd772b1bfd 100644 --- a/src/test/ui/empty/empty-struct-braces-pat-3.stderr +++ b/src/test/ui/empty/empty-struct-braces-pat-3.stderr @@ -1,6 +1,9 @@ error[E0532]: expected tuple struct/variant, found struct variant `E::Empty3` --> $DIR/empty-struct-braces-pat-3.rs:17:9 | +LL | Empty3 {} + | --------- `E::Empty3` defined here +... LL | E::Empty3() => () | ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`? @@ -16,6 +19,9 @@ LL | XE::XEmpty3() => () error[E0532]: expected tuple struct/variant, found struct variant `E::Empty3` --> $DIR/empty-struct-braces-pat-3.rs:25:9 | +LL | Empty3 {} + | --------- `E::Empty3` defined here +... LL | E::Empty3(..) => () | ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`? diff --git a/src/test/ui/empty/empty-struct-tuple-pat.stderr b/src/test/ui/empty/empty-struct-tuple-pat.stderr index 6c15e7bf282ce..4b828c0d942e3 100644 --- a/src/test/ui/empty/empty-struct-tuple-pat.stderr +++ b/src/test/ui/empty/empty-struct-tuple-pat.stderr @@ -19,8 +19,11 @@ LL | XEmpty6 => () error[E0532]: expected unit struct/variant or constant, found tuple variant `E::Empty4` --> $DIR/empty-struct-tuple-pat.rs:29:9 | +LL | Empty4() + | -------- `E::Empty4` defined here +... LL | E::Empty4 => () - | ^^^^^^^^^ did you mean `E::Empty4 ( /* fields */ )`? + | ^^^^^^^^^ did you mean `E::Empty4( /* fields */ )`? error[E0532]: expected unit struct/variant or constant, found tuple variant `XE::XEmpty5` --> $DIR/empty-struct-tuple-pat.rs:33:9 @@ -29,7 +32,7 @@ LL | XE::XEmpty5 => (), | ^^^^------- | | | | | help: a unit variant with a similar name exists: `XEmpty4` - | did you mean `XE::XEmpty5 ( /* fields */ )`? + | did you mean `XE::XEmpty5( /* fields */ )`? error: aborting due to 4 previous errors diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr index ec240003f9182..ce631ca4bf786 100644 --- a/src/test/ui/error-codes/E0423.stderr +++ b/src/test/ui/error-codes/E0423.stderr @@ -27,6 +27,9 @@ LL | for _ in (std::ops::Range { start: 0, end: 10 }) {} error[E0423]: expected function, found struct `Foo` --> $DIR/E0423.rs:4:13 | +LL | struct Foo { a: bool }; + | ---------------------- `Foo` defined here +LL | LL | let f = Foo(); | ^^^ | | diff --git a/src/test/ui/issues/issue-19086.stderr b/src/test/ui/issues/issue-19086.stderr index d2b9b90890e3c..e2229cbc20922 100644 --- a/src/test/ui/issues/issue-19086.stderr +++ b/src/test/ui/issues/issue-19086.stderr @@ -1,6 +1,9 @@ error[E0532]: expected tuple struct/variant, found struct variant `FooB` --> $DIR/issue-19086.rs:10:9 | +LL | FooB { x: i32, y: i32 } + | ----------------------- `FooB` defined here +... LL | FooB(a, b) => println!("{} {}", a, b), | ^^^^ did you mean `FooB { /* fields */ }`? diff --git a/src/test/ui/issues/issue-32004.stderr b/src/test/ui/issues/issue-32004.stderr index b56fa949acb7e..e9a5e217392a6 100644 --- a/src/test/ui/issues/issue-32004.stderr +++ b/src/test/ui/issues/issue-32004.stderr @@ -1,11 +1,14 @@ error[E0532]: expected unit struct/variant or constant, found tuple variant `Foo::Bar` --> $DIR/issue-32004.rs:10:9 | +LL | Bar(i32), + | -------- `Foo::Bar` defined here +... LL | Foo::Bar => {} | ^^^^^--- | | | | | help: a unit variant with a similar name exists: `Baz` - | did you mean `Foo::Bar ( /* fields */ )`? + | did you mean `Foo::Bar( /* fields */ )`? error[E0532]: expected tuple struct/variant, found unit struct `S` --> $DIR/issue-32004.rs:16:9 diff --git a/src/test/ui/issues/issue-63983.stderr b/src/test/ui/issues/issue-63983.stderr index 67acd1d57c27a..8949c475b6f72 100644 --- a/src/test/ui/issues/issue-63983.stderr +++ b/src/test/ui/issues/issue-63983.stderr @@ -1,12 +1,18 @@ error[E0532]: expected unit struct/variant or constant, found tuple variant `MyEnum::Tuple` --> $DIR/issue-63983.rs:8:9 | +LL | Tuple(i32), + | ---------- `MyEnum::Tuple` defined here +... LL | MyEnum::Tuple => "", - | ^^^^^^^^^^^^^ did you mean `MyEnum::Tuple ( /* fields */ )`? + | ^^^^^^^^^^^^^ did you mean `MyEnum::Tuple( /* fields */ )`? error[E0532]: expected unit struct/variant or constant, found struct variant `MyEnum::Struct` --> $DIR/issue-63983.rs:10:9 | +LL | Struct{ s: i32 }, + | ---------------- `MyEnum::Struct` defined here +... LL | MyEnum::Struct => "", | ^^^^^^^^^^^^^^ did you mean `MyEnum::Struct { /* fields */ }`? diff --git a/src/test/ui/namespace/namespace-mix.stderr b/src/test/ui/namespace/namespace-mix.stderr index 249ad1c584421..900e9cf54c97a 100644 --- a/src/test/ui/namespace/namespace-mix.stderr +++ b/src/test/ui/namespace/namespace-mix.stderr @@ -37,6 +37,9 @@ LL | use namespace_mix::xm2::S; error[E0423]: expected value, found struct variant `m7::V` --> $DIR/namespace-mix.rs:100:11 | +LL | V {}, + | ---- `m7::V` defined here +... LL | check(m7::V); | ^^^^^ did you mean `m7::V { /* fields */ }`? help: a tuple variant with a similar name exists diff --git a/src/test/ui/parser/recover-from-bad-variant.stderr b/src/test/ui/parser/recover-from-bad-variant.stderr index b46d3ca9c233c..32bb88d31c4c7 100644 --- a/src/test/ui/parser/recover-from-bad-variant.stderr +++ b/src/test/ui/parser/recover-from-bad-variant.stderr @@ -12,6 +12,9 @@ LL | let x = Enum::Foo(a: 3, b: 4); error[E0532]: expected tuple struct/variant, found struct variant `Enum::Foo` --> $DIR/recover-from-bad-variant.rs:10:9 | +LL | Foo { a: usize, b: usize }, + | -------------------------- `Enum::Foo` defined here +... LL | Enum::Foo(a, b) => {} | ^^^^^^^^^ did you mean `Enum::Foo { /* fields */ }`? diff --git a/src/test/ui/resolve/issue-18252.stderr b/src/test/ui/resolve/issue-18252.stderr index 293f290f82fd9..c76e5ef8b3617 100644 --- a/src/test/ui/resolve/issue-18252.stderr +++ b/src/test/ui/resolve/issue-18252.stderr @@ -1,6 +1,9 @@ error[E0423]: expected function, found struct variant `Foo::Variant` --> $DIR/issue-18252.rs:6:13 | +LL | Variant { x: usize } + | -------------------- `Foo::Variant` defined here +... LL | let f = Foo::Variant(42); | ^^^^^^^^^^^^ did you mean `Foo::Variant { /* fields */ }`? diff --git a/src/test/ui/resolve/issue-19452.stderr b/src/test/ui/resolve/issue-19452.stderr index 56a0e397b854c..4d20f1580264c 100644 --- a/src/test/ui/resolve/issue-19452.stderr +++ b/src/test/ui/resolve/issue-19452.stderr @@ -1,6 +1,9 @@ error[E0423]: expected value, found struct variant `Homura::Madoka` --> $DIR/issue-19452.rs:10:18 | +LL | Madoka { age: u32 } + | ------------------- `Homura::Madoka` defined here +... LL | let homura = Homura::Madoka; | ^^^^^^^^^^^^^^ did you mean `Homura::Madoka { /* fields */ }`? diff --git a/src/test/ui/resolve/issue-39226.stderr b/src/test/ui/resolve/issue-39226.stderr index c97fb4db6be6b..d9a28e63dce8b 100644 --- a/src/test/ui/resolve/issue-39226.stderr +++ b/src/test/ui/resolve/issue-39226.stderr @@ -1,6 +1,9 @@ error[E0423]: expected value, found struct `Handle` --> $DIR/issue-39226.rs:11:17 | +LL | struct Handle {} + | ---------------- `Handle` defined here +... LL | handle: Handle | ^^^^^^ | | diff --git a/src/test/ui/resolve/issue-6702.stderr b/src/test/ui/resolve/issue-6702.stderr index 9a46f0d774262..3fdc7acb274e5 100644 --- a/src/test/ui/resolve/issue-6702.stderr +++ b/src/test/ui/resolve/issue-6702.stderr @@ -1,8 +1,13 @@ error[E0423]: expected function, found struct `Monster` --> $DIR/issue-6702.rs:7:14 | -LL | let _m = Monster(); - | ^^^^^^^ did you mean `Monster { /* fields */ }`? +LL | / struct Monster { +LL | | damage: isize +LL | | } + | |_- `Monster` defined here +... +LL | let _m = Monster(); + | ^^^^^^^ did you mean `Monster { /* fields */ }`? error: aborting due to previous error diff --git a/src/test/ui/resolve/privacy-enum-ctor.stderr b/src/test/ui/resolve/privacy-enum-ctor.stderr index 2538bbbf8067f..7d8d1d0abfc21 100644 --- a/src/test/ui/resolve/privacy-enum-ctor.stderr +++ b/src/test/ui/resolve/privacy-enum-ctor.stderr @@ -33,8 +33,13 @@ LL | m::Z::Unit; error[E0423]: expected value, found struct variant `Z::Struct` --> $DIR/privacy-enum-ctor.rs:29:20 | -LL | let _: Z = Z::Struct; - | ^^^^^^^^^ did you mean `Z::Struct { /* fields */ }`? +LL | / Struct { +LL | | s: u8, +LL | | }, + | |_____________- `Z::Struct` defined here +... +LL | let _: Z = Z::Struct; + | ^^^^^^^^^ did you mean `Z::Struct { /* fields */ }`? error[E0423]: expected value, found enum `m::E` --> $DIR/privacy-enum-ctor.rs:41:16 @@ -63,8 +68,13 @@ LL | use std::f64::consts::E; error[E0423]: expected value, found struct variant `m::E::Struct` --> $DIR/privacy-enum-ctor.rs:45:16 | -LL | let _: E = m::E::Struct; - | ^^^^^^^^^^^^ did you mean `m::E::Struct { /* fields */ }`? +LL | / Struct { +LL | | s: u8, +LL | | }, + | |_________- `m::E::Struct` defined here +... +LL | let _: E = m::E::Struct; + | ^^^^^^^^^^^^ did you mean `m::E::Struct { /* fields */ }`? error[E0423]: expected value, found enum `E` --> $DIR/privacy-enum-ctor.rs:49:16 @@ -89,8 +99,13 @@ LL | use std::f64::consts::E; error[E0423]: expected value, found struct variant `E::Struct` --> $DIR/privacy-enum-ctor.rs:53:16 | -LL | let _: E = E::Struct; - | ^^^^^^^^^ did you mean `E::Struct { /* fields */ }`? +LL | / Struct { +LL | | s: u8, +LL | | }, + | |_________- `E::Struct` defined here +... +LL | let _: E = E::Struct; + | ^^^^^^^^^ did you mean `E::Struct { /* fields */ }`? error[E0412]: cannot find type `Z` in this scope --> $DIR/privacy-enum-ctor.rs:57:12 @@ -151,8 +166,13 @@ LL | use m::n::Z; error[E0423]: expected value, found struct variant `m::n::Z::Struct` --> $DIR/privacy-enum-ctor.rs:64:16 | -LL | let _: Z = m::n::Z::Struct; - | ^^^^^^^^^^^^^^^ did you mean `m::n::Z::Struct { /* fields */ }`? +LL | / Struct { +LL | | s: u8, +LL | | }, + | |_____________- `m::n::Z::Struct` defined here +... +LL | let _: Z = m::n::Z::Struct; + | ^^^^^^^^^^^^^^^ did you mean `m::n::Z::Struct { /* fields */ }`? error[E0412]: cannot find type `Z` in this scope --> $DIR/privacy-enum-ctor.rs:68:12 diff --git a/src/test/ui/resolve/privacy-struct-ctor.stderr b/src/test/ui/resolve/privacy-struct-ctor.stderr index 72d62fe45ce74..979367bc623fd 100644 --- a/src/test/ui/resolve/privacy-struct-ctor.stderr +++ b/src/test/ui/resolve/privacy-struct-ctor.stderr @@ -16,8 +16,13 @@ LL | S; error[E0423]: expected value, found struct `S2` --> $DIR/privacy-struct-ctor.rs:38:5 | -LL | S2; - | ^^ did you mean `S2 { /* fields */ }`? +LL | / pub struct S2 { +LL | | s: u8 +LL | | } + | |_____- `S2` defined here +... +LL | S2; + | ^^ did you mean `S2 { /* fields */ }`? error[E0423]: expected value, found struct `xcrate::S` --> $DIR/privacy-struct-ctor.rs:43:5 diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr index 28b331bdbdcbc..1af0f7a191e80 100644 --- a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr +++ b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr @@ -1,6 +1,9 @@ error[E0423]: expected value, found struct variant `E::B` --> $DIR/fn-or-tuple-struct-without-args.rs:36:16 | +LL | B { a: usize }, + | -------------- `E::B` defined here +... LL | let _: E = E::B; | ^^^- | | | diff --git a/src/test/ui/suggestions/issue-61226.stderr b/src/test/ui/suggestions/issue-61226.stderr index 6d7d98ac6a16b..fbcfba6653f27 100644 --- a/src/test/ui/suggestions/issue-61226.stderr +++ b/src/test/ui/suggestions/issue-61226.stderr @@ -1,6 +1,9 @@ error[E0423]: expected value, found struct `X` --> $DIR/issue-61226.rs:3:10 | +LL | struct X {} + | ----------- `X` defined here +LL | fn main() { LL | vec![X]; //… | ^ did you mean `X { /* fields */ }`?