diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index a60cad0de9f76..8129b27eb6a73 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1219,6 +1219,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, @@ -1233,6 +1242,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, diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 8613ec86b4a73..0f6f906ea55c9 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -164,41 +164,63 @@ 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 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 { + 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", - 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)) + struct_span_err!( + tcx.sess, + span, + E0599, + "no {} named `{}` found for type `{}` in the current scope", + type_str, + item_name, + ty_string + ) } else { - self.tcx.sess.diagnostic().struct_dummy() + 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)(...). if let Some(expr) = rcvr_expr { @@ -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) { diff --git a/src/test/compile-fail/bogus-tag.rs b/src/test/compile-fail/bogus-tag.rs index c388d47da6e51..a629f76d8b3e9 100644 --- a/src/test/compile-fail/bogus-tag.rs +++ b/src/test/compile-fail/bogus-tag.rs @@ -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` } } diff --git a/src/test/compile-fail/empty-struct-braces-expr.rs b/src/test/compile-fail/empty-struct-braces-expr.rs index d4e85e9744d64..3096e8f831368 100644 --- a/src/test/compile-fail/empty-struct-braces-expr.rs +++ b/src/test/compile-fail/empty-struct-braces-expr.rs @@ -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 } diff --git a/src/test/compile-fail/issue-22933-2.rs b/src/test/compile-fail/issue-22933-2.rs index 97456c2da87fe..583f2ace4ba05 100644 --- a/src/test/compile-fail/issue-22933-2.rs +++ b/src/test/compile-fail/issue-22933-2.rs @@ -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() {} diff --git a/src/test/compile-fail/issue-23173.rs b/src/test/compile-fail/issue-23173.rs index 946e4b9e96e47..c0983eb0e5257 100644 --- a/src/test/compile-fail/issue-23173.rs +++ b/src/test/compile-fail/issue-23173.rs @@ -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` } diff --git a/src/test/compile-fail/issue-23217.rs b/src/test/compile-fail/issue-23217.rs index 95f6526f11559..cce0b99c04d79 100644 --- a/src/test/compile-fail/issue-23217.rs +++ b/src/test/compile-fail/issue-23217.rs @@ -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() {} diff --git a/src/test/compile-fail/issue-28971.rs b/src/test/compile-fail/issue-28971.rs index 1d14b71a40e4f..10be4d6210d7a 100644 --- a/src/test/compile-fail/issue-28971.rs +++ b/src/test/compile-fail/issue-28971.rs @@ -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` _ => (), } }); diff --git a/src/test/ui/impl-trait/issue-21659-show-relevant-trait-impls-3.stderr b/src/test/ui/impl-trait/issue-21659-show-relevant-trait-impls-3.stderr index 3bc281726ef3a..297694568493d 100644 --- a/src/test/ui/impl-trait/issue-21659-show-relevant-trait-impls-3.stderr +++ b/src/test/ui/impl-trait/issue-21659-show-relevant-trait-impls-3.stderr @@ -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); | ^^^ | diff --git a/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr b/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr index d3dbb77490b87..52d3931011a77 100644 --- a/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr +++ b/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr @@ -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()); | ^^^^^^^^ | diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr index 23f115858cd5e..6ea62341f7277 100644 --- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr +++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr @@ -67,6 +67,9 @@ error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::box 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(); | ^^^^^^ | @@ -157,6 +160,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(); | ^^^^^^^ | @@ -177,6 +183,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(); | ^^^^^^^ | diff --git a/src/test/ui/method-call-err-msg.stderr b/src/test/ui/method-call-err-msg.stderr index c39c62daf9efe..1d4558cad6717 100644 --- a/src/test/ui/method-call-err-msg.stderr +++ b/src/test/ui/method-call-err-msg.stderr @@ -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 | ^^^^ | diff --git a/src/test/ui/rfc-2005-default-binding-mode/no-double-error.stderr b/src/test/ui/rfc-2005-default-binding-mode/no-double-error.stderr index da065eea897b7..4a83b606dccd9 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/no-double-error.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/no-double-error.stderr @@ -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 diff --git a/src/test/ui/span/issue-7575.stderr b/src/test/ui/span/issue-7575.stderr index 08ec2a87fcdc4..9b248f49e08b8 100644 --- a/src/test/ui/span/issue-7575.stderr +++ b/src/test/ui/span/issue-7575.stderr @@ -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) | ^^^ | diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr b/src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr index 0ca61127634bc..bbe8fe7345aa0 100644 --- a/src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr +++ b/src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr @@ -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 where F: FnMut() -> u32 { + | ------------------------------------- method `closure` not found for this +... 17 | o.closure(); | ^^^^^^^ field, not a method | diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr b/src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr index c6f134f118db7..a9211e1864e3b 100644 --- a/src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr +++ b/src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr @@ -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 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 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 u32 {func}>` in the current scope --> $DIR/issue-2392.rs:60:12 | +25 | struct Obj 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 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 u32 {func}>` in the current scope --> $DIR/issue-2392.rs:77:12 | +25 | struct Obj 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 u32 {func}>` error[E0599]: no method named `not_closure` found for type `Obj u32 {func}>` in the current scope --> $DIR/issue-2392.rs:81:12 | +25 | struct Obj 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 u32 {fun error[E0599]: no method named `closure` found for type `Obj + 'static>>` in the current scope --> $DIR/issue-2392.rs:86:24 | +25 | struct Obj 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 $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 | diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-32128.stderr b/src/test/ui/suggestions/confuse-field-and-method/issue-32128.stderr index a45e70d48c99e..d6a837a17ae1c 100644 --- a/src/test/ui/suggestions/confuse-field-and-method/issue-32128.stderr +++ b/src/test/ui/suggestions/confuse-field-and-method/issue-32128.stderr @@ -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 | diff --git a/src/test/ui/suggestions/confuse-field-and-method/private-field.stderr b/src/test/ui/suggestions/confuse-field-and-method/private-field.stderr index 9451926626028..dd0081782f418 100644 --- a/src/test/ui/suggestions/confuse-field-and-method/private-field.stderr +++ b/src/test/ui/suggestions/confuse-field-and-method/private-field.stderr @@ -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 diff --git a/src/test/ui/suggestions/suggest-methods.stderr b/src/test/ui/suggestions/suggest-methods.stderr index 41beb73b1bc35..30e3bbd997976 100644 --- a/src/test/ui/suggestions/suggest-methods.stderr +++ b/src/test/ui/suggestions/suggest-methods.stderr @@ -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); | ^^^ |