Skip to content

Commit 0a2ddcc

Browse files
authored
Rollup merge of rust-lang#64691 - estebank:unexpected-variant, r=Centril
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.
2 parents 06c6894 + 2ae9016 commit 0a2ddcc

20 files changed

+126
-24
lines changed

src/librustc_resolve/late/diagnostics.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
348348
_ => false,
349349
};
350350

351-
let mut bad_struct_syntax_suggestion = || {
351+
let mut bad_struct_syntax_suggestion = |def_id: DefId| {
352352
let (followed_by_brace, closing_brace) = self.followed_by_brace(span);
353353
let mut suggested = false;
354354
match source {
@@ -374,6 +374,9 @@ impl<'a> LateResolutionVisitor<'a, '_> {
374374
_ => {}
375375
}
376376
if !suggested {
377+
if let Some(span) = self.r.definitions.opt_span(def_id) {
378+
err.span_label(span, &format!("`{}` defined here", path_str));
379+
}
377380
err.span_label(
378381
span,
379382
format!("did you mean `{} {{ /* fields */ }}`?", path_str),
@@ -437,18 +440,21 @@ impl<'a> LateResolutionVisitor<'a, '_> {
437440
);
438441
}
439442
} else {
440-
bad_struct_syntax_suggestion();
443+
bad_struct_syntax_suggestion(def_id);
441444
}
442445
}
443-
(Res::Def(DefKind::Union, _), _) |
444-
(Res::Def(DefKind::Variant, _), _) |
445-
(Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _), _) if ns == ValueNS => {
446-
bad_struct_syntax_suggestion();
446+
(Res::Def(DefKind::Union, def_id), _) |
447+
(Res::Def(DefKind::Variant, def_id), _) |
448+
(Res::Def(DefKind::Ctor(_, CtorKind::Fictive), def_id), _) if ns == ValueNS => {
449+
bad_struct_syntax_suggestion(def_id);
447450
}
448-
(Res::Def(DefKind::Ctor(_, CtorKind::Fn), _), _) if ns == ValueNS => {
451+
(Res::Def(DefKind::Ctor(_, CtorKind::Fn), def_id), _) if ns == ValueNS => {
452+
if let Some(span) = self.r.definitions.opt_span(def_id) {
453+
err.span_label(span, &format!("`{}` defined here", path_str));
454+
}
449455
err.span_label(
450456
span,
451-
format!("did you mean `{} ( /* fields */ )`?", path_str),
457+
format!("did you mean `{}( /* fields */ )`?", path_str),
452458
);
453459
}
454460
(Res::SelfTy(..), _) if ns == ValueNS => {

src/test/ui/empty/empty-struct-braces-expr.stderr

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0423]: expected value, found struct `Empty1`
22
--> $DIR/empty-struct-braces-expr.rs:15:14
33
|
4+
LL | struct Empty1 {}
5+
| ---------------- `Empty1` defined here
6+
...
47
LL | let e1 = Empty1;
58
| ^^^^^^
69
| |
@@ -10,6 +13,9 @@ LL | let e1 = Empty1;
1013
error[E0423]: expected function, found struct `Empty1`
1114
--> $DIR/empty-struct-braces-expr.rs:16:14
1215
|
16+
LL | struct Empty1 {}
17+
| ---------------- `Empty1` defined here
18+
...
1319
LL | let e1 = Empty1();
1420
| ^^^^^^
1521
| |
@@ -19,12 +25,18 @@ LL | let e1 = Empty1();
1925
error[E0423]: expected value, found struct variant `E::Empty3`
2026
--> $DIR/empty-struct-braces-expr.rs:17:14
2127
|
28+
LL | Empty3 {}
29+
| --------- `E::Empty3` defined here
30+
...
2231
LL | let e3 = E::Empty3;
2332
| ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`?
2433

2534
error[E0423]: expected function, found struct variant `E::Empty3`
2635
--> $DIR/empty-struct-braces-expr.rs:18:14
2736
|
37+
LL | Empty3 {}
38+
| --------- `E::Empty3` defined here
39+
...
2840
LL | let e3 = E::Empty3();
2941
| ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`?
3042

src/test/ui/empty/empty-struct-braces-pat-1.stderr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0532]: expected unit struct/variant or constant, found struct variant `E::Empty3`
22
--> $DIR/empty-struct-braces-pat-1.rs:24:9
33
|
4+
LL | Empty3 {}
5+
| --------- `E::Empty3` defined here
6+
...
47
LL | E::Empty3 => ()
58
| ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`?
69

src/test/ui/empty/empty-struct-braces-pat-2.stderr

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0532]: expected tuple struct/variant, found struct `Empty1`
22
--> $DIR/empty-struct-braces-pat-2.rs:15:9
33
|
4+
LL | struct Empty1 {}
5+
| ---------------- `Empty1` defined here
6+
...
47
LL | Empty1() => ()
58
| ^^^^^^
69
| |
@@ -19,6 +22,9 @@ LL | XEmpty1() => ()
1922
error[E0532]: expected tuple struct/variant, found struct `Empty1`
2023
--> $DIR/empty-struct-braces-pat-2.rs:21:9
2124
|
25+
LL | struct Empty1 {}
26+
| ---------------- `Empty1` defined here
27+
...
2228
LL | Empty1(..) => ()
2329
| ^^^^^^
2430
| |

src/test/ui/empty/empty-struct-braces-pat-3.stderr

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0532]: expected tuple struct/variant, found struct variant `E::Empty3`
22
--> $DIR/empty-struct-braces-pat-3.rs:17:9
33
|
4+
LL | Empty3 {}
5+
| --------- `E::Empty3` defined here
6+
...
47
LL | E::Empty3() => ()
58
| ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`?
69

@@ -16,6 +19,9 @@ LL | XE::XEmpty3() => ()
1619
error[E0532]: expected tuple struct/variant, found struct variant `E::Empty3`
1720
--> $DIR/empty-struct-braces-pat-3.rs:25:9
1821
|
22+
LL | Empty3 {}
23+
| --------- `E::Empty3` defined here
24+
...
1925
LL | E::Empty3(..) => ()
2026
| ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`?
2127

src/test/ui/empty/empty-struct-tuple-pat.stderr

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@ LL | XEmpty6 => ()
1919
error[E0532]: expected unit struct/variant or constant, found tuple variant `E::Empty4`
2020
--> $DIR/empty-struct-tuple-pat.rs:29:9
2121
|
22+
LL | Empty4()
23+
| -------- `E::Empty4` defined here
24+
...
2225
LL | E::Empty4 => ()
23-
| ^^^^^^^^^ did you mean `E::Empty4 ( /* fields */ )`?
26+
| ^^^^^^^^^ did you mean `E::Empty4( /* fields */ )`?
2427

2528
error[E0532]: expected unit struct/variant or constant, found tuple variant `XE::XEmpty5`
2629
--> $DIR/empty-struct-tuple-pat.rs:33:9
@@ -29,7 +32,7 @@ LL | XE::XEmpty5 => (),
2932
| ^^^^-------
3033
| | |
3134
| | help: a unit variant with a similar name exists: `XEmpty4`
32-
| did you mean `XE::XEmpty5 ( /* fields */ )`?
35+
| did you mean `XE::XEmpty5( /* fields */ )`?
3336

3437
error: aborting due to 4 previous errors
3538

src/test/ui/error-codes/E0423.stderr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ LL | for _ in (std::ops::Range { start: 0, end: 10 }) {}
2727
error[E0423]: expected function, found struct `Foo`
2828
--> $DIR/E0423.rs:4:13
2929
|
30+
LL | struct Foo { a: bool };
31+
| ---------------------- `Foo` defined here
32+
LL |
3033
LL | let f = Foo();
3134
| ^^^
3235
| |

src/test/ui/issues/issue-19086.stderr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0532]: expected tuple struct/variant, found struct variant `FooB`
22
--> $DIR/issue-19086.rs:10:9
33
|
4+
LL | FooB { x: i32, y: i32 }
5+
| ----------------------- `FooB` defined here
6+
...
47
LL | FooB(a, b) => println!("{} {}", a, b),
58
| ^^^^ did you mean `FooB { /* fields */ }`?
69

src/test/ui/issues/issue-32004.stderr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
error[E0532]: expected unit struct/variant or constant, found tuple variant `Foo::Bar`
22
--> $DIR/issue-32004.rs:10:9
33
|
4+
LL | Bar(i32),
5+
| -------- `Foo::Bar` defined here
6+
...
47
LL | Foo::Bar => {}
58
| ^^^^^---
69
| | |
710
| | help: a unit variant with a similar name exists: `Baz`
8-
| did you mean `Foo::Bar ( /* fields */ )`?
11+
| did you mean `Foo::Bar( /* fields */ )`?
912

1013
error[E0532]: expected tuple struct/variant, found unit struct `S`
1114
--> $DIR/issue-32004.rs:16:9

src/test/ui/issues/issue-63983.stderr

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
error[E0532]: expected unit struct/variant or constant, found tuple variant `MyEnum::Tuple`
22
--> $DIR/issue-63983.rs:8:9
33
|
4+
LL | Tuple(i32),
5+
| ---------- `MyEnum::Tuple` defined here
6+
...
47
LL | MyEnum::Tuple => "",
5-
| ^^^^^^^^^^^^^ did you mean `MyEnum::Tuple ( /* fields */ )`?
8+
| ^^^^^^^^^^^^^ did you mean `MyEnum::Tuple( /* fields */ )`?
69

710
error[E0532]: expected unit struct/variant or constant, found struct variant `MyEnum::Struct`
811
--> $DIR/issue-63983.rs:10:9
912
|
13+
LL | Struct{ s: i32 },
14+
| ---------------- `MyEnum::Struct` defined here
15+
...
1016
LL | MyEnum::Struct => "",
1117
| ^^^^^^^^^^^^^^ did you mean `MyEnum::Struct { /* fields */ }`?
1218

src/test/ui/namespace/namespace-mix.stderr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ LL | use namespace_mix::xm2::S;
3737
error[E0423]: expected value, found struct variant `m7::V`
3838
--> $DIR/namespace-mix.rs:100:11
3939
|
40+
LL | V {},
41+
| ---- `m7::V` defined here
42+
...
4043
LL | check(m7::V);
4144
| ^^^^^ did you mean `m7::V { /* fields */ }`?
4245
help: a tuple variant with a similar name exists

src/test/ui/parser/recover-from-bad-variant.stderr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ LL | let x = Enum::Foo(a: 3, b: 4);
1212
error[E0532]: expected tuple struct/variant, found struct variant `Enum::Foo`
1313
--> $DIR/recover-from-bad-variant.rs:10:9
1414
|
15+
LL | Foo { a: usize, b: usize },
16+
| -------------------------- `Enum::Foo` defined here
17+
...
1518
LL | Enum::Foo(a, b) => {}
1619
| ^^^^^^^^^ did you mean `Enum::Foo { /* fields */ }`?
1720

src/test/ui/resolve/issue-18252.stderr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0423]: expected function, found struct variant `Foo::Variant`
22
--> $DIR/issue-18252.rs:6:13
33
|
4+
LL | Variant { x: usize }
5+
| -------------------- `Foo::Variant` defined here
6+
...
47
LL | let f = Foo::Variant(42);
58
| ^^^^^^^^^^^^ did you mean `Foo::Variant { /* fields */ }`?
69

src/test/ui/resolve/issue-19452.stderr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0423]: expected value, found struct variant `Homura::Madoka`
22
--> $DIR/issue-19452.rs:10:18
33
|
4+
LL | Madoka { age: u32 }
5+
| ------------------- `Homura::Madoka` defined here
6+
...
47
LL | let homura = Homura::Madoka;
58
| ^^^^^^^^^^^^^^ did you mean `Homura::Madoka { /* fields */ }`?
69

src/test/ui/resolve/issue-39226.stderr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0423]: expected value, found struct `Handle`
22
--> $DIR/issue-39226.rs:11:17
33
|
4+
LL | struct Handle {}
5+
| ---------------- `Handle` defined here
6+
...
47
LL | handle: Handle
58
| ^^^^^^
69
| |

src/test/ui/resolve/issue-6702.stderr

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
error[E0423]: expected function, found struct `Monster`
22
--> $DIR/issue-6702.rs:7:14
33
|
4-
LL | let _m = Monster();
5-
| ^^^^^^^ did you mean `Monster { /* fields */ }`?
4+
LL | / struct Monster {
5+
LL | | damage: isize
6+
LL | | }
7+
| |_- `Monster` defined here
8+
...
9+
LL | let _m = Monster();
10+
| ^^^^^^^ did you mean `Monster { /* fields */ }`?
611

712
error: aborting due to previous error
813

src/test/ui/resolve/privacy-enum-ctor.stderr

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,13 @@ LL | m::Z::Unit;
3333
error[E0423]: expected value, found struct variant `Z::Struct`
3434
--> $DIR/privacy-enum-ctor.rs:29:20
3535
|
36-
LL | let _: Z = Z::Struct;
37-
| ^^^^^^^^^ did you mean `Z::Struct { /* fields */ }`?
36+
LL | / Struct {
37+
LL | | s: u8,
38+
LL | | },
39+
| |_____________- `Z::Struct` defined here
40+
...
41+
LL | let _: Z = Z::Struct;
42+
| ^^^^^^^^^ did you mean `Z::Struct { /* fields */ }`?
3843

3944
error[E0423]: expected value, found enum `m::E`
4045
--> $DIR/privacy-enum-ctor.rs:41:16
@@ -63,8 +68,13 @@ LL | use std::f64::consts::E;
6368
error[E0423]: expected value, found struct variant `m::E::Struct`
6469
--> $DIR/privacy-enum-ctor.rs:45:16
6570
|
66-
LL | let _: E = m::E::Struct;
67-
| ^^^^^^^^^^^^ did you mean `m::E::Struct { /* fields */ }`?
71+
LL | / Struct {
72+
LL | | s: u8,
73+
LL | | },
74+
| |_________- `m::E::Struct` defined here
75+
...
76+
LL | let _: E = m::E::Struct;
77+
| ^^^^^^^^^^^^ did you mean `m::E::Struct { /* fields */ }`?
6878

6979
error[E0423]: expected value, found enum `E`
7080
--> $DIR/privacy-enum-ctor.rs:49:16
@@ -89,8 +99,13 @@ LL | use std::f64::consts::E;
8999
error[E0423]: expected value, found struct variant `E::Struct`
90100
--> $DIR/privacy-enum-ctor.rs:53:16
91101
|
92-
LL | let _: E = E::Struct;
93-
| ^^^^^^^^^ did you mean `E::Struct { /* fields */ }`?
102+
LL | / Struct {
103+
LL | | s: u8,
104+
LL | | },
105+
| |_________- `E::Struct` defined here
106+
...
107+
LL | let _: E = E::Struct;
108+
| ^^^^^^^^^ did you mean `E::Struct { /* fields */ }`?
94109

95110
error[E0412]: cannot find type `Z` in this scope
96111
--> $DIR/privacy-enum-ctor.rs:57:12
@@ -151,8 +166,13 @@ LL | use m::n::Z;
151166
error[E0423]: expected value, found struct variant `m::n::Z::Struct`
152167
--> $DIR/privacy-enum-ctor.rs:64:16
153168
|
154-
LL | let _: Z = m::n::Z::Struct;
155-
| ^^^^^^^^^^^^^^^ did you mean `m::n::Z::Struct { /* fields */ }`?
169+
LL | / Struct {
170+
LL | | s: u8,
171+
LL | | },
172+
| |_____________- `m::n::Z::Struct` defined here
173+
...
174+
LL | let _: Z = m::n::Z::Struct;
175+
| ^^^^^^^^^^^^^^^ did you mean `m::n::Z::Struct { /* fields */ }`?
156176

157177
error[E0412]: cannot find type `Z` in this scope
158178
--> $DIR/privacy-enum-ctor.rs:68:12

src/test/ui/resolve/privacy-struct-ctor.stderr

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,13 @@ LL | S;
1616
error[E0423]: expected value, found struct `S2`
1717
--> $DIR/privacy-struct-ctor.rs:38:5
1818
|
19-
LL | S2;
20-
| ^^ did you mean `S2 { /* fields */ }`?
19+
LL | / pub struct S2 {
20+
LL | | s: u8
21+
LL | | }
22+
| |_____- `S2` defined here
23+
...
24+
LL | S2;
25+
| ^^ did you mean `S2 { /* fields */ }`?
2126

2227
error[E0423]: expected value, found struct `xcrate::S`
2328
--> $DIR/privacy-struct-ctor.rs:43:5

src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0423]: expected value, found struct variant `E::B`
22
--> $DIR/fn-or-tuple-struct-without-args.rs:36:16
33
|
4+
LL | B { a: usize },
5+
| -------------- `E::B` defined here
6+
...
47
LL | let _: E = E::B;
58
| ^^^-
69
| | |

src/test/ui/suggestions/issue-61226.stderr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0423]: expected value, found struct `X`
22
--> $DIR/issue-61226.rs:3:10
33
|
4+
LL | struct X {}
5+
| ----------- `X` defined here
6+
LL | fn main() {
47
LL | vec![X]; //…
58
| ^ did you mean `X { /* fields */ }`?
69

0 commit comments

Comments
 (0)