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 {
match self.sty {
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 {
match self.sty {
TyInfer(FreshTy(_)) => true,

View File

@ -164,40 +164,62 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
};
match error {
MethodError::NoMatch(NoMatchData { static_candidates: static_sources,
unsatisfied_predicates,
out_of_scope_traits,
lev_candidate,
mode,
.. }) => {
MethodError::NoMatch(NoMatchData {
static_candidates: static_sources,
unsatisfied_predicates,
out_of_scope_traits,
lev_candidate,
mode,
..
}) => {
let tcx = self.tcx;
let actual = self.resolve_type_vars_if_possible(&rcvr_ty);
let mut err = if !actual.references_error() {
struct_span_err!(tcx.sess, span, E0599,
"no {} named `{}` found for type `{}` in the \
current scope",
if mode == Mode::MethodCall {
"method"
} 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))
let ty_string = self.ty_to_string(actual);
let is_method = mode == Mode::MethodCall;
let type_str = if is_method {
"method"
} else if actual.is_enum() {
"variant"
} 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,
// 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) {

View File

@ -10,11 +10,14 @@
enum color { rgb(isize, isize, isize), rgba(isize, isize, isize, isize), }
//~^ NOTE variant `hsl` not found here
fn main() {
let red: color = color::rgb(255, 0, 0);
match red {
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 function, found struct `XEmpty1`
let xe3 = XE::Empty3; //~ ERROR no associated item 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
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
// except according to those terms.
enum Delicious {
enum Delicious { //~ NOTE variant `PIE` not found here
Pie = 0x1,
Apple = 0x2,
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() {}

View File

@ -9,9 +9,27 @@
// except according to those terms.
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 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
// except according to those terms.
pub enum SomeEnum {
pub enum SomeEnum { //~ NOTE variant `A` not found here
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() {}

View File

@ -10,13 +10,15 @@
// This should not cause an ICE
enum Foo {
enum Foo { //~ NOTE variant `Baz` not found here
Bar(u8)
}
fn main(){
foo(|| {
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
--> $DIR/issue-21659-show-relevant-trait-impls-3.rs:30:8
|
23 | struct Bar;
| ----------- method `foo` not found for this
...
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
--> $DIR/method-suggestion-no-duplication.rs:19:15
|
14 | struct Foo;
| ----------- method `is_empty` not found for this
...
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
--> $DIR/no-method-suggested-traits.rs:62:9
|
14 | struct Foo;
| ----------- method `method` not found for this
...
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
--> $DIR/no-method-suggested-traits.rs:107:9
|
14 | struct Foo;
| ----------- method `method3` not found for this
...
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
--> $DIR/no-method-suggested-traits.rs:115:12
|
15 | enum Bar { X }
| -------- method `method3` not found for this
...
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
--> $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
| ^^^^
|

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
|
18 | u32::XXX => { }
| ^^^^^^^^
| ^^^^^^^^ associated item not found in `u32`
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
--> $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)
| ^^^
|

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
--> $DIR/issue-18343.rs:17:7
|
11 | struct Obj<F> where F: FnMut() -> u32 {
| ------------------------------------- method `closure` not found for this
...
17 | o.closure();
| ^^^^^^^ 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
--> $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
| ^^^^^^^ 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
--> $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();
| ^^^^^^^^^^^ 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
--> $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
| ^^^^^^^ 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
--> $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
| ^^^^^^^^^^^^^ 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
--> $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
| ^^^^^^^^^^^^^ 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
--> $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
| ^^^^^^^ 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
--> $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();
| ^^^^^^^^^^^ 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
--> $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
| ^^^^^^^ 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
--> $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
| ^^ 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
--> $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
| ^^ 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
--> $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
| ^^ field, not a method
|

View File

@ -1,6 +1,9 @@
error[E0599]: no method named `example` found for type `Example` in the current scope
--> $DIR/issue-32128.rs:22:10
|
11 | struct Example {
| -------------- method `example` not found for this
...
22 | demo.example(1);
| ^^^^^^^ 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
--> $DIR/private-field.rs:26:23
|
12 | pub struct Dog {
| -------------- method `dog_age` not found for this
...
26 | let dog_age = dog.dog_age();
| ^^^^^^^ 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
--> $DIR/suggest-methods.rs:28:7
|
11 | struct Foo;
| ----------- method `bat` not found for this
...
28 | f.bat(1.0);
| ^^^
|