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:
commit
a6031a2ccf
19 changed files with 171 additions and 40 deletions
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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`
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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`
|
||||
}
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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`
|
||||
_ => (),
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
| ^^^
|
||||
|
|
||||
|
|
|
@ -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());
|
||||
| ^^^^^^^^
|
||||
|
|
||||
|
|
|
@ -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();
|
||||
| ^^^^^^^
|
||||
|
|
||||
|
|
|
@ -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
|
||||
| ^^^^
|
||||
|
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
| ^^^
|
||||
|
|
||||
|
|
|
@ -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
|
||||
|
|
||||
|
|
|
@ -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
|
||||
|
|
||||
|
|
|
@ -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
|
||||
|
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
| ^^^
|
||||
|
|
||||
|
|
Loading…
Reference in a new issue