Skip to content

Commit a6031a2

Browse files
committed
Auto merge of #46024 - estebank:no-variant, r=petrochenkov
Use the proper term when using non-existing variant When using a non-existing variant, function or associated item, refer to the proper term, instead of defaulting to "associated item" in diagnostics. Fix #28972. ``` error[E0599]: no variant named `Quux` found for type `Foo` in the current scope --> file.rs:7:9 | 7 | Foo::Quux(..) =>(), | ^^^^^^^^^^^^^ ```
2 parents 10ef344 + b450aff commit a6031a2

19 files changed

+170
-39
lines changed

src/librustc/ty/sty.rs

+16
Original file line numberDiff line numberDiff line change
@@ -1365,6 +1365,15 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
13651365
}
13661366
}
13671367

1368+
pub fn is_enum(&self) -> bool {
1369+
match self.sty {
1370+
TyAdt(adt_def, _) => {
1371+
adt_def.is_enum()
1372+
}
1373+
_ => false,
1374+
}
1375+
}
1376+
13681377
pub fn is_closure(&self) -> bool {
13691378
match self.sty {
13701379
TyClosure(..) => true,
@@ -1386,6 +1395,13 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
13861395
}
13871396
}
13881397

1398+
pub fn is_fresh_ty(&self) -> bool {
1399+
match self.sty {
1400+
TyInfer(FreshTy(_)) => true,
1401+
_ => false,
1402+
}
1403+
}
1404+
13891405
pub fn is_fresh(&self) -> bool {
13901406
match self.sty {
13911407
TyInfer(FreshTy(_)) => true,

src/librustc_typeck/check/method/suggest.rs

+52-28
Original file line numberDiff line numberDiff line change
@@ -164,41 +164,63 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
164164
};
165165

166166
match error {
167-
MethodError::NoMatch(NoMatchData { static_candidates: static_sources,
168-
unsatisfied_predicates,
169-
out_of_scope_traits,
170-
lev_candidate,
171-
mode,
172-
.. }) => {
167+
MethodError::NoMatch(NoMatchData {
168+
static_candidates: static_sources,
169+
unsatisfied_predicates,
170+
out_of_scope_traits,
171+
lev_candidate,
172+
mode,
173+
..
174+
}) => {
173175
let tcx = self.tcx;
174176

175177
let actual = self.resolve_type_vars_if_possible(&rcvr_ty);
178+
let ty_string = self.ty_to_string(actual);
179+
let is_method = mode == Mode::MethodCall;
180+
let type_str = if is_method {
181+
"method"
182+
} else if actual.is_enum() {
183+
"variant"
184+
} else {
185+
match (item_name.as_str().chars().next(), actual.is_fresh_ty()) {
186+
(Some(name), false) if name.is_lowercase() => {
187+
"function or associated item"
188+
}
189+
(Some(_), false) => "associated item",
190+
(Some(_), true) | (None, false) => {
191+
"variant or associated item"
192+
}
193+
(None, true) => "variant",
194+
}
195+
};
176196
let mut err = if !actual.references_error() {
177-
struct_span_err!(tcx.sess, span, E0599,
178-
"no {} named `{}` found for type `{}` in the \
179-
current scope",
180-
if mode == Mode::MethodCall {
181-
"method"
182-
} else {
183-
match item_name.as_str().chars().next() {
184-
Some(name) => {
185-
if name.is_lowercase() {
186-
"function or associated item"
187-
} else {
188-
"associated item"
189-
}
190-
},
191-
None => {
192-
""
193-
},
194-
}
195-
},
196-
item_name,
197-
self.ty_to_string(actual))
197+
struct_span_err!(
198+
tcx.sess,
199+
span,
200+
E0599,
201+
"no {} named `{}` found for type `{}` in the current scope",
202+
type_str,
203+
item_name,
204+
ty_string
205+
)
198206
} else {
199-
self.tcx.sess.diagnostic().struct_dummy()
207+
tcx.sess.diagnostic().struct_dummy()
200208
};
201209

210+
if let Some(def) = actual.ty_adt_def() {
211+
if let Some(full_sp) = tcx.hir.span_if_local(def.did) {
212+
let def_sp = tcx.sess.codemap().def_span(full_sp);
213+
err.span_label(def_sp, format!("{} `{}` not found {}",
214+
type_str,
215+
item_name,
216+
if def.is_enum() && !is_method {
217+
"here"
218+
} else {
219+
"for this"
220+
}));
221+
}
222+
}
223+
202224
// If the method name is the name of a field with a function or closure type,
203225
// give a helping note that it has to be called as (x.f)(...).
204226
if let Some(expr) = rcvr_expr {
@@ -240,6 +262,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
240262
_ => {}
241263
}
242264
}
265+
} else {
266+
err.span_label(span, format!("{} not found in `{}`", type_str, ty_string));
243267
}
244268

245269
if self.is_fn_ty(&rcvr_ty, span) {

src/test/compile-fail/bogus-tag.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,14 @@
1010

1111

1212
enum color { rgb(isize, isize, isize), rgba(isize, isize, isize, isize), }
13+
//~^ NOTE variant `hsl` not found here
1314

1415
fn main() {
1516
let red: color = color::rgb(255, 0, 0);
1617
match red {
1718
color::rgb(r, g, b) => { println!("rgb"); }
18-
color::hsl(h, s, l) => { println!("hsl"); } //~ ERROR no function
19+
color::hsl(h, s, l) => { println!("hsl"); }
20+
//~^ ERROR no variant
21+
//~| NOTE variant not found in `color`
1922
}
2023
}

src/test/compile-fail/empty-struct-braces-expr.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@ fn main() {
2929

3030
let xe1 = XEmpty1; //~ ERROR expected value, found struct `XEmpty1`
3131
let xe1 = XEmpty1(); //~ ERROR expected function, found struct `XEmpty1`
32-
let xe3 = XE::Empty3; //~ ERROR no associated item named `Empty3` found for type
33-
let xe3 = XE::Empty3(); //~ ERROR no associated item named `Empty3` found for type
32+
let xe3 = XE::Empty3; //~ ERROR no variant named `Empty3` found for type
33+
let xe3 = XE::Empty3(); //~ ERROR no variant named `Empty3` found for type
3434
}

src/test/compile-fail/issue-22933-2.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
enum Delicious {
11+
enum Delicious { //~ NOTE variant `PIE` not found here
1212
Pie = 0x1,
1313
Apple = 0x2,
1414
ApplePie = Delicious::Apple as isize | Delicious::PIE as isize,
15-
//~^ ERROR no associated item named `PIE` found for type `Delicious`
15+
//~^ ERROR no variant named `PIE` found for type `Delicious`
16+
//~| NOTE variant not found in `Delicious`
1617
}
1718

1819
fn main() {}

src/test/compile-fail/issue-23173.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,27 @@
99
// except according to those terms.
1010

1111
enum Token { LeftParen, RightParen, Plus, Minus, /* etc */ }
12+
//~^ NOTE variant `Homura` not found here
13+
struct Struct {
14+
//~^ NOTE function or associated item `method` not found for this
15+
//~| NOTE function or associated item `method` not found for this
16+
//~| NOTE associated item `Assoc` not found for this
17+
a: usize,
18+
}
1219

1320
fn use_token(token: &Token) { unimplemented!() }
1421

1522
fn main() {
16-
use_token(&Token::Homura); //~ ERROR no associated item named
23+
use_token(&Token::Homura);
24+
//~^ ERROR no variant named `Homura`
25+
//~| NOTE variant not found in `Token`
26+
Struct::method();
27+
//~^ ERROR no function or associated item named `method` found for type
28+
//~| NOTE function or associated item not found in `Struct`
29+
Struct::method;
30+
//~^ ERROR no function or associated item named `method` found for type
31+
//~| NOTE function or associated item not found in `Struct`
32+
Struct::Assoc;
33+
//~^ ERROR no associated item named `Assoc` found for type `Struct` in
34+
//~| NOTE associated item not found in `Struct`
1735
}

src/test/compile-fail/issue-23217.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
pub enum SomeEnum {
11+
pub enum SomeEnum { //~ NOTE variant `A` not found here
1212
B = SomeEnum::A,
13-
//~^ ERROR no associated item named `A` found for type `SomeEnum`
13+
//~^ ERROR no variant named `A` found for type `SomeEnum`
14+
//~| NOTE variant not found in `SomeEnum`
1415
}
1516

1617
fn main() {}

src/test/compile-fail/issue-28971.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@
1010

1111
// This should not cause an ICE
1212

13-
enum Foo {
13+
enum Foo { //~ NOTE variant `Baz` not found here
1414
Bar(u8)
1515
}
1616
fn main(){
1717
foo(|| {
1818
match Foo::Bar(1) {
19-
Foo::Baz(..) => (), //~ ERROR no associated
19+
Foo::Baz(..) => (),
20+
//~^ ERROR no variant named `Baz` found for type `Foo`
21+
//~| NOTE variant not found in `Foo`
2022
_ => (),
2123
}
2224
});

src/test/ui/impl-trait/issue-21659-show-relevant-trait-impls-3.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0599]: no method named `foo` found for type `Bar` in the current scope
22
--> $DIR/issue-21659-show-relevant-trait-impls-3.rs:30:8
33
|
4+
23 | struct Bar;
5+
| ----------- method `foo` not found for this
6+
...
47
30 | f1.foo(1usize);
58
| ^^^
69
|

src/test/ui/impl-trait/method-suggestion-no-duplication.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0599]: no method named `is_empty` found for type `Foo` in the current scope
22
--> $DIR/method-suggestion-no-duplication.rs:19:15
33
|
4+
14 | struct Foo;
5+
| ----------- method `is_empty` not found for this
6+
...
47
19 | foo(|s| s.is_empty());
58
| ^^^^^^^^
69
|

src/test/ui/impl-trait/no-method-suggested-traits.stderr

+9
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ help: the following trait is implemented but not in scope, perhaps add a `use` f
8585
error[E0599]: no method named `method` found for type `Foo` in the current scope
8686
--> $DIR/no-method-suggested-traits.rs:62:9
8787
|
88+
14 | struct Foo;
89+
| ----------- method `method` not found for this
90+
...
8891
62 | Foo.method();
8992
| ^^^^^^
9093
|
@@ -175,6 +178,9 @@ error[E0599]: no method named `method2` found for type `std::rc::Rc<&mut std::bo
175178
error[E0599]: no method named `method3` found for type `Foo` in the current scope
176179
--> $DIR/no-method-suggested-traits.rs:107:9
177180
|
181+
14 | struct Foo;
182+
| ----------- method `method3` not found for this
183+
...
178184
107 | Foo.method3();
179185
| ^^^^^^^
180186
|
@@ -195,6 +201,9 @@ error[E0599]: no method named `method3` found for type `std::rc::Rc<&mut std::bo
195201
error[E0599]: no method named `method3` found for type `Bar` in the current scope
196202
--> $DIR/no-method-suggested-traits.rs:115:12
197203
|
204+
15 | enum Bar { X }
205+
| -------- method `method3` not found for this
206+
...
198207
115 | Bar::X.method3();
199208
| ^^^^^^^
200209
|

src/test/ui/method-call-err-msg.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ error[E0061]: this function takes 2 parameters but 1 parameter was supplied
2828
error[E0599]: no method named `take` found for type `Foo` in the current scope
2929
--> $DIR/method-call-err-msg.rs:34:7
3030
|
31+
13 | pub struct Foo;
32+
| --------------- method `take` not found for this
33+
...
3134
34 | .take() //~ ERROR no method named `take` found for type `Foo` in the current scope
3235
| ^^^^
3336
|

src/test/ui/rfc-2005-default-binding-mode/no-double-error.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0599]: no associated item named `XXX` found for type `u32` in the current
22
--> $DIR/no-double-error.rs:18:9
33
|
44
18 | u32::XXX => { }
5-
| ^^^^^^^^
5+
| ^^^^^^^^ associated item not found in `u32`
66

77
error: aborting due to previous error
88

src/test/ui/span/issue-7575.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ note: candidate #3 is defined in the trait `UnusedTrait`
3333
error[E0599]: no method named `fff` found for type `Myisize` in the current scope
3434
--> $DIR/issue-7575.rs:74:30
3535
|
36+
48 | struct Myisize(isize);
37+
| ---------------------- method `fff` not found for this
38+
...
3639
74 | u.f8(42) + u.f9(342) + m.fff(42)
3740
| ^^^
3841
|

src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0599]: no method named `closure` found for type `Obj<[closure@$DIR/issue-18343.rs:16:28: 16:33]>` in the current scope
22
--> $DIR/issue-18343.rs:17:7
33
|
4+
11 | struct Obj<F> where F: FnMut() -> u32 {
5+
| ------------------------------------- method `closure` not found for this
6+
...
47
17 | o.closure();
58
| ^^^^^^^ field, not a method
69
|

0 commit comments

Comments
 (0)