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(..) =>(),
  |         ^^^^^^^^^^^^^
```
This commit is contained in:
bors 2017-11-23 05:53:08 +00:00
commit a6031a2ccf
19 changed files with 171 additions and 40 deletions

View file

@ -1365,6 +1365,15 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
} }
} }
pub fn is_enum(&self) -> bool {
match self.sty {
TyAdt(adt_def, _) => {
adt_def.is_enum()
}
_ => false,
}
}
pub fn is_closure(&self) -> bool { pub fn is_closure(&self) -> bool {
match self.sty { match self.sty {
TyClosure(..) => true, TyClosure(..) => true,
@ -1386,6 +1395,13 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
} }
} }
pub fn is_fresh_ty(&self) -> bool {
match self.sty {
TyInfer(FreshTy(_)) => true,
_ => false,
}
}
pub fn is_fresh(&self) -> bool { pub fn is_fresh(&self) -> bool {
match self.sty { match self.sty {
TyInfer(FreshTy(_)) => true, TyInfer(FreshTy(_)) => true,

View file

@ -164,40 +164,62 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}; };
match error { match error {
MethodError::NoMatch(NoMatchData { static_candidates: static_sources, MethodError::NoMatch(NoMatchData {
unsatisfied_predicates, static_candidates: static_sources,
out_of_scope_traits, unsatisfied_predicates,
lev_candidate, out_of_scope_traits,
mode, lev_candidate,
.. }) => { mode,
..
}) => {
let tcx = self.tcx; let tcx = self.tcx;
let actual = self.resolve_type_vars_if_possible(&rcvr_ty); let actual = self.resolve_type_vars_if_possible(&rcvr_ty);
let mut err = if !actual.references_error() { let ty_string = self.ty_to_string(actual);
struct_span_err!(tcx.sess, span, E0599, let is_method = mode == Mode::MethodCall;
"no {} named `{}` found for type `{}` in the \ let type_str = if is_method {
current scope", "method"
if mode == Mode::MethodCall { } else if actual.is_enum() {
"method" "variant"
} else {
match item_name.as_str().chars().next() {
Some(name) => {
if name.is_lowercase() {
"function or associated item"
} else {
"associated item"
}
},
None => {
""
},
}
},
item_name,
self.ty_to_string(actual))
} else { } else {
self.tcx.sess.diagnostic().struct_dummy() match (item_name.as_str().chars().next(), actual.is_fresh_ty()) {
(Some(name), false) if name.is_lowercase() => {
"function or associated item"
}
(Some(_), false) => "associated item",
(Some(_), true) | (None, false) => {
"variant or associated item"
}
(None, true) => "variant",
}
}; };
let mut err = if !actual.references_error() {
struct_span_err!(
tcx.sess,
span,
E0599,
"no {} named `{}` found for type `{}` in the current scope",
type_str,
item_name,
ty_string
)
} else {
tcx.sess.diagnostic().struct_dummy()
};
if let Some(def) = actual.ty_adt_def() {
if let Some(full_sp) = tcx.hir.span_if_local(def.did) {
let def_sp = tcx.sess.codemap().def_span(full_sp);
err.span_label(def_sp, format!("{} `{}` not found {}",
type_str,
item_name,
if def.is_enum() && !is_method {
"here"
} else {
"for this"
}));
}
}
// If the method name is the name of a field with a function or closure type, // If the method name is the name of a field with a function or closure type,
// give a helping note that it has to be called as (x.f)(...). // give a helping note that it has to be called as (x.f)(...).
@ -240,6 +262,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
_ => {} _ => {}
} }
} }
} else {
err.span_label(span, format!("{} not found in `{}`", type_str, ty_string));
} }
if self.is_fn_ty(&rcvr_ty, span) { if self.is_fn_ty(&rcvr_ty, span) {

View file

@ -10,11 +10,14 @@
enum color { rgb(isize, isize, isize), rgba(isize, isize, isize, isize), } enum color { rgb(isize, isize, isize), rgba(isize, isize, isize, isize), }
//~^ NOTE variant `hsl` not found here
fn main() { fn main() {
let red: color = color::rgb(255, 0, 0); let red: color = color::rgb(255, 0, 0);
match red { match red {
color::rgb(r, g, b) => { println!("rgb"); } color::rgb(r, g, b) => { println!("rgb"); }
color::hsl(h, s, l) => { println!("hsl"); } //~ ERROR no function color::hsl(h, s, l) => { println!("hsl"); }
//~^ ERROR no variant
//~| NOTE variant not found in `color`
} }
} }

View file

@ -29,6 +29,6 @@ fn main() {
let xe1 = XEmpty1; //~ ERROR expected value, found struct `XEmpty1` let xe1 = XEmpty1; //~ ERROR expected value, found struct `XEmpty1`
let xe1 = XEmpty1(); //~ ERROR expected function, found struct `XEmpty1` let xe1 = XEmpty1(); //~ ERROR expected function, found struct `XEmpty1`
let xe3 = XE::Empty3; //~ ERROR no associated item named `Empty3` found for type let xe3 = XE::Empty3; //~ ERROR no variant named `Empty3` found for type
let xe3 = XE::Empty3(); //~ ERROR no associated item named `Empty3` found for type let xe3 = XE::Empty3(); //~ ERROR no variant named `Empty3` found for type
} }

View file

@ -8,11 +8,12 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
enum Delicious { enum Delicious { //~ NOTE variant `PIE` not found here
Pie = 0x1, Pie = 0x1,
Apple = 0x2, Apple = 0x2,
ApplePie = Delicious::Apple as isize | Delicious::PIE as isize, ApplePie = Delicious::Apple as isize | Delicious::PIE as isize,
//~^ ERROR no associated item named `PIE` found for type `Delicious` //~^ ERROR no variant named `PIE` found for type `Delicious`
//~| NOTE variant not found in `Delicious`
} }
fn main() {} fn main() {}

View file

@ -9,9 +9,27 @@
// except according to those terms. // except according to those terms.
enum Token { LeftParen, RightParen, Plus, Minus, /* etc */ } enum Token { LeftParen, RightParen, Plus, Minus, /* etc */ }
//~^ NOTE variant `Homura` not found here
struct Struct {
//~^ NOTE function or associated item `method` not found for this
//~| NOTE function or associated item `method` not found for this
//~| NOTE associated item `Assoc` not found for this
a: usize,
}
fn use_token(token: &Token) { unimplemented!() } fn use_token(token: &Token) { unimplemented!() }
fn main() { fn main() {
use_token(&Token::Homura); //~ ERROR no associated item named use_token(&Token::Homura);
//~^ ERROR no variant named `Homura`
//~| NOTE variant not found in `Token`
Struct::method();
//~^ ERROR no function or associated item named `method` found for type
//~| NOTE function or associated item not found in `Struct`
Struct::method;
//~^ ERROR no function or associated item named `method` found for type
//~| NOTE function or associated item not found in `Struct`
Struct::Assoc;
//~^ ERROR no associated item named `Assoc` found for type `Struct` in
//~| NOTE associated item not found in `Struct`
} }

View file

@ -8,9 +8,10 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
pub enum SomeEnum { pub enum SomeEnum { //~ NOTE variant `A` not found here
B = SomeEnum::A, B = SomeEnum::A,
//~^ ERROR no associated item named `A` found for type `SomeEnum` //~^ ERROR no variant named `A` found for type `SomeEnum`
//~| NOTE variant not found in `SomeEnum`
} }
fn main() {} fn main() {}

View file

@ -10,13 +10,15 @@
// This should not cause an ICE // This should not cause an ICE
enum Foo { enum Foo { //~ NOTE variant `Baz` not found here
Bar(u8) Bar(u8)
} }
fn main(){ fn main(){
foo(|| { foo(|| {
match Foo::Bar(1) { match Foo::Bar(1) {
Foo::Baz(..) => (), //~ ERROR no associated Foo::Baz(..) => (),
//~^ ERROR no variant named `Baz` found for type `Foo`
//~| NOTE variant not found in `Foo`
_ => (), _ => (),
} }
}); });

View file

@ -1,6 +1,9 @@
error[E0599]: no method named `foo` found for type `Bar` in the current scope error[E0599]: no method named `foo` found for type `Bar` in the current scope
--> $DIR/issue-21659-show-relevant-trait-impls-3.rs:30:8 --> $DIR/issue-21659-show-relevant-trait-impls-3.rs:30:8
| |
23 | struct Bar;
| ----------- method `foo` not found for this
...
30 | f1.foo(1usize); 30 | f1.foo(1usize);
| ^^^ | ^^^
| |

View file

@ -1,6 +1,9 @@
error[E0599]: no method named `is_empty` found for type `Foo` in the current scope error[E0599]: no method named `is_empty` found for type `Foo` in the current scope
--> $DIR/method-suggestion-no-duplication.rs:19:15 --> $DIR/method-suggestion-no-duplication.rs:19:15
| |
14 | struct Foo;
| ----------- method `is_empty` not found for this
...
19 | foo(|s| s.is_empty()); 19 | foo(|s| s.is_empty());
| ^^^^^^^^ | ^^^^^^^^
| |

View file

@ -85,6 +85,9 @@ help: the following trait is implemented but not in scope, perhaps add a `use` f
error[E0599]: no method named `method` found for type `Foo` in the current scope error[E0599]: no method named `method` found for type `Foo` in the current scope
--> $DIR/no-method-suggested-traits.rs:62:9 --> $DIR/no-method-suggested-traits.rs:62:9
| |
14 | struct Foo;
| ----------- method `method` not found for this
...
62 | Foo.method(); 62 | Foo.method();
| ^^^^^^ | ^^^^^^
| |
@ -175,6 +178,9 @@ error[E0599]: no method named `method2` found for type `std::rc::Rc<&mut std::bo
error[E0599]: no method named `method3` found for type `Foo` in the current scope error[E0599]: no method named `method3` found for type `Foo` in the current scope
--> $DIR/no-method-suggested-traits.rs:107:9 --> $DIR/no-method-suggested-traits.rs:107:9
| |
14 | struct Foo;
| ----------- method `method3` not found for this
...
107 | Foo.method3(); 107 | Foo.method3();
| ^^^^^^^ | ^^^^^^^
| |
@ -195,6 +201,9 @@ error[E0599]: no method named `method3` found for type `std::rc::Rc<&mut std::bo
error[E0599]: no method named `method3` found for type `Bar` in the current scope error[E0599]: no method named `method3` found for type `Bar` in the current scope
--> $DIR/no-method-suggested-traits.rs:115:12 --> $DIR/no-method-suggested-traits.rs:115:12
| |
15 | enum Bar { X }
| -------- method `method3` not found for this
...
115 | Bar::X.method3(); 115 | Bar::X.method3();
| ^^^^^^^ | ^^^^^^^
| |

View file

@ -28,6 +28,9 @@ error[E0061]: this function takes 2 parameters but 1 parameter was supplied
error[E0599]: no method named `take` found for type `Foo` in the current scope error[E0599]: no method named `take` found for type `Foo` in the current scope
--> $DIR/method-call-err-msg.rs:34:7 --> $DIR/method-call-err-msg.rs:34:7
| |
13 | pub struct Foo;
| --------------- method `take` not found for this
...
34 | .take() //~ ERROR no method named `take` found for type `Foo` in the current scope 34 | .take() //~ ERROR no method named `take` found for type `Foo` in the current scope
| ^^^^ | ^^^^
| |

View file

@ -2,7 +2,7 @@ error[E0599]: no associated item named `XXX` found for type `u32` in the current
--> $DIR/no-double-error.rs:18:9 --> $DIR/no-double-error.rs:18:9
| |
18 | u32::XXX => { } 18 | u32::XXX => { }
| ^^^^^^^^ | ^^^^^^^^ associated item not found in `u32`
error: aborting due to previous error error: aborting due to previous error

View file

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

View file

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

View file

@ -1,6 +1,9 @@
error[E0599]: no method named `closure` found for type `Obj<[closure@$DIR/issue-2392.rs:49:36: 49:41]>` in the current scope error[E0599]: no method named `closure` found for type `Obj<[closure@$DIR/issue-2392.rs:49:36: 49:41]>` in the current scope
--> $DIR/issue-2392.rs:50:15 --> $DIR/issue-2392.rs:50:15
| |
25 | struct Obj<F> where F: FnOnce() -> u32 {
| -------------------------------------- method `closure` not found for this
...
50 | o_closure.closure(); //~ ERROR no method named `closure` found 50 | o_closure.closure(); //~ ERROR no method named `closure` found
| ^^^^^^^ field, not a method | ^^^^^^^ field, not a method
| |
@ -9,6 +12,9 @@ error[E0599]: no method named `closure` found for type `Obj<[closure@$DIR/issue-
error[E0599]: no method named `not_closure` found for type `Obj<[closure@$DIR/issue-2392.rs:49:36: 49:41]>` in the current scope error[E0599]: no method named `not_closure` found for type `Obj<[closure@$DIR/issue-2392.rs:49:36: 49:41]>` in the current scope
--> $DIR/issue-2392.rs:54:15 --> $DIR/issue-2392.rs:54:15
| |
25 | struct Obj<F> where F: FnOnce() -> u32 {
| -------------------------------------- method `not_closure` not found for this
...
54 | o_closure.not_closure(); 54 | o_closure.not_closure();
| ^^^^^^^^^^^ field, not a method | ^^^^^^^^^^^ field, not a method
| |
@ -17,6 +23,9 @@ error[E0599]: no method named `not_closure` found for type `Obj<[closure@$DIR/is
error[E0599]: no method named `closure` found for type `Obj<fn() -> u32 {func}>` in the current scope error[E0599]: no method named `closure` found for type `Obj<fn() -> u32 {func}>` in the current scope
--> $DIR/issue-2392.rs:60:12 --> $DIR/issue-2392.rs:60:12
| |
25 | struct Obj<F> where F: FnOnce() -> u32 {
| -------------------------------------- method `closure` not found for this
...
60 | o_func.closure(); //~ ERROR no method named `closure` found 60 | o_func.closure(); //~ ERROR no method named `closure` found
| ^^^^^^^ field, not a method | ^^^^^^^ field, not a method
| |
@ -25,6 +34,9 @@ error[E0599]: no method named `closure` found for type `Obj<fn() -> u32 {func}>`
error[E0599]: no method named `boxed_closure` found for type `BoxedObj` in the current scope error[E0599]: no method named `boxed_closure` found for type `BoxedObj` in the current scope
--> $DIR/issue-2392.rs:65:14 --> $DIR/issue-2392.rs:65:14
| |
30 | struct BoxedObj {
| --------------- method `boxed_closure` not found for this
...
65 | boxed_fn.boxed_closure();//~ ERROR no method named `boxed_closure` found 65 | boxed_fn.boxed_closure();//~ ERROR no method named `boxed_closure` found
| ^^^^^^^^^^^^^ field, not a method | ^^^^^^^^^^^^^ field, not a method
| |
@ -33,6 +45,9 @@ error[E0599]: no method named `boxed_closure` found for type `BoxedObj` in the c
error[E0599]: no method named `boxed_closure` found for type `BoxedObj` in the current scope error[E0599]: no method named `boxed_closure` found for type `BoxedObj` in the current scope
--> $DIR/issue-2392.rs:70:19 --> $DIR/issue-2392.rs:70:19
| |
30 | struct BoxedObj {
| --------------- method `boxed_closure` not found for this
...
70 | boxed_closure.boxed_closure();//~ ERROR no method named `boxed_closure` found 70 | boxed_closure.boxed_closure();//~ ERROR no method named `boxed_closure` found
| ^^^^^^^^^^^^^ field, not a method | ^^^^^^^^^^^^^ field, not a method
| |
@ -41,6 +56,9 @@ error[E0599]: no method named `boxed_closure` found for type `BoxedObj` in the c
error[E0599]: no method named `closure` found for type `Obj<fn() -> u32 {func}>` in the current scope error[E0599]: no method named `closure` found for type `Obj<fn() -> u32 {func}>` in the current scope
--> $DIR/issue-2392.rs:77:12 --> $DIR/issue-2392.rs:77:12
| |
25 | struct Obj<F> where F: FnOnce() -> u32 {
| -------------------------------------- method `closure` not found for this
...
77 | w.wrap.closure();//~ ERROR no method named `closure` found 77 | w.wrap.closure();//~ ERROR no method named `closure` found
| ^^^^^^^ field, not a method | ^^^^^^^ field, not a method
| |
@ -49,6 +67,9 @@ error[E0599]: no method named `closure` found for type `Obj<fn() -> u32 {func}>`
error[E0599]: no method named `not_closure` found for type `Obj<fn() -> u32 {func}>` in the current scope error[E0599]: no method named `not_closure` found for type `Obj<fn() -> u32 {func}>` in the current scope
--> $DIR/issue-2392.rs:81:12 --> $DIR/issue-2392.rs:81:12
| |
25 | struct Obj<F> where F: FnOnce() -> u32 {
| -------------------------------------- method `not_closure` not found for this
...
81 | w.wrap.not_closure(); 81 | w.wrap.not_closure();
| ^^^^^^^^^^^ field, not a method | ^^^^^^^^^^^ field, not a method
| |
@ -57,6 +78,9 @@ error[E0599]: no method named `not_closure` found for type `Obj<fn() -> u32 {fun
error[E0599]: no method named `closure` found for type `Obj<std::boxed::Box<std::boxed::FnBox<(), Output=u32> + 'static>>` in the current scope error[E0599]: no method named `closure` found for type `Obj<std::boxed::Box<std::boxed::FnBox<(), Output=u32> + 'static>>` in the current scope
--> $DIR/issue-2392.rs:86:24 --> $DIR/issue-2392.rs:86:24
| |
25 | struct Obj<F> where F: FnOnce() -> u32 {
| -------------------------------------- method `closure` not found for this
...
86 | check_expression().closure();//~ ERROR no method named `closure` found 86 | check_expression().closure();//~ ERROR no method named `closure` found
| ^^^^^^^ field, not a method | ^^^^^^^ field, not a method
| |
@ -65,6 +89,9 @@ error[E0599]: no method named `closure` found for type `Obj<std::boxed::Box<std:
error[E0599]: no method named `f1` found for type `FuncContainer` in the current scope error[E0599]: no method named `f1` found for type `FuncContainer` in the current scope
--> $DIR/issue-2392.rs:94:31 --> $DIR/issue-2392.rs:94:31
| |
15 | struct FuncContainer {
| -------------------- method `f1` not found for this
...
94 | (*self.container).f1(1); //~ ERROR no method named `f1` found 94 | (*self.container).f1(1); //~ ERROR no method named `f1` found
| ^^ field, not a method | ^^ field, not a method
| |
@ -73,6 +100,9 @@ error[E0599]: no method named `f1` found for type `FuncContainer` in the current
error[E0599]: no method named `f2` found for type `FuncContainer` in the current scope error[E0599]: no method named `f2` found for type `FuncContainer` in the current scope
--> $DIR/issue-2392.rs:97:31 --> $DIR/issue-2392.rs:97:31
| |
15 | struct FuncContainer {
| -------------------- method `f2` not found for this
...
97 | (*self.container).f2(1); //~ ERROR no method named `f2` found 97 | (*self.container).f2(1); //~ ERROR no method named `f2` found
| ^^ field, not a method | ^^ field, not a method
| |
@ -81,6 +111,9 @@ error[E0599]: no method named `f2` found for type `FuncContainer` in the current
error[E0599]: no method named `f3` found for type `FuncContainer` in the current scope error[E0599]: no method named `f3` found for type `FuncContainer` in the current scope
--> $DIR/issue-2392.rs:100:31 --> $DIR/issue-2392.rs:100:31
| |
15 | struct FuncContainer {
| -------------------- method `f3` not found for this
...
100 | (*self.container).f3(1); //~ ERROR no method named `f3` found 100 | (*self.container).f3(1); //~ ERROR no method named `f3` found
| ^^ field, not a method | ^^ field, not a method
| |

View file

@ -1,6 +1,9 @@
error[E0599]: no method named `example` found for type `Example` in the current scope error[E0599]: no method named `example` found for type `Example` in the current scope
--> $DIR/issue-32128.rs:22:10 --> $DIR/issue-32128.rs:22:10
| |
11 | struct Example {
| -------------- method `example` not found for this
...
22 | demo.example(1); 22 | demo.example(1);
| ^^^^^^^ field, not a method | ^^^^^^^ field, not a method
| |

View file

@ -1,6 +1,9 @@
error[E0599]: no method named `dog_age` found for type `animal::Dog` in the current scope error[E0599]: no method named `dog_age` found for type `animal::Dog` in the current scope
--> $DIR/private-field.rs:26:23 --> $DIR/private-field.rs:26:23
| |
12 | pub struct Dog {
| -------------- method `dog_age` not found for this
...
26 | let dog_age = dog.dog_age(); 26 | let dog_age = dog.dog_age();
| ^^^^^^^ private field, not a method | ^^^^^^^ private field, not a method

View file

@ -1,6 +1,9 @@
error[E0599]: no method named `bat` found for type `Foo` in the current scope error[E0599]: no method named `bat` found for type `Foo` in the current scope
--> $DIR/suggest-methods.rs:28:7 --> $DIR/suggest-methods.rs:28:7
| |
11 | struct Foo;
| ----------- method `bat` not found for this
...
28 | f.bat(1.0); 28 | f.bat(1.0);
| ^^^ | ^^^
| |