From 422d553b5200b87bdb6098ff879980e42d30f78c Mon Sep 17 00:00:00 2001 From: Mohit Agarwal Date: Thu, 29 Sep 2016 00:33:06 +0530 Subject: [PATCH] improve snippet for "did you mean `x`" r? @nikomatsakis cc @jonathandturner Fixes #36164 --- src/librustc_typeck/check/mod.rs | 17 +++++++----- .../attempted-access-non-fatal.rs | 6 +++-- src/test/compile-fail/cast-rfc0401.rs | 3 ++- .../derived-errors/issue-30580.rs | 3 ++- src/test/compile-fail/issue-11004.rs | 4 +-- src/test/compile-fail/issue-14721.rs | 3 +-- src/test/compile-fail/issue-19244-2.rs | 2 +- src/test/compile-fail/issue-23253.rs | 3 ++- src/test/compile-fail/issue-24363.rs | 2 +- src/test/compile-fail/issue-24365.rs | 10 ++++--- src/test/compile-fail/issue-31011.rs | 3 ++- src/test/compile-fail/issue-36164.rs | 27 +++++++++++++++++++ src/test/compile-fail/no-type-for-node-ice.rs | 3 ++- src/test/compile-fail/struct-fields-typo.rs | 4 +-- .../compile-fail/struct-pat-derived-error.rs | 2 +- .../compile-fail/union/union-suggest-field.rs | 4 +-- src/test/compile-fail/unsafe-fn-autoderef.rs | 2 +- .../incremental/struct_change_field_name.rs | 4 +-- .../macro-backtrace-invalid-internals.stderr | 12 ++++----- 19 files changed, 77 insertions(+), 37 deletions(-) create mode 100644 src/test/compile-fail/issue-36164.rs diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index ee00cb2f5a3e4..acdf5be391786 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2959,24 +2959,27 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { .emit(); self.tcx().types.err } else { - let mut err = self.type_error_struct(expr.span, |actual| { - format!("attempted access of field `{}` on type `{}`, \ - but no field with that name was found", + let mut err = self.type_error_struct(field.span, |actual| { + format!("no field `{}` on type `{}`", field.node, actual) }, expr_t); match expr_t.sty { ty::TyAdt(def, _) if !def.is_enum() => { if let Some(suggested_field_name) = Self::suggest_field_name(def.struct_variant(), field, vec![]) { - err.span_help(field.span, - &format!("did you mean `{}`?", suggested_field_name)); - }; + err.span_label(field.span, + &format!("did you mean `{}`?", suggested_field_name)); + } else { + err.span_label(field.span, &format!("unknown field")); + } } ty::TyRawPtr(..) => { err.note(&format!("`{0}` is a native pointer; perhaps you need to deref with \ `(*{0}).{1}`", pprust::expr_to_string(base), field.node)); } - _ => {} + _ => { + err.span_label(field.span, &format!("unknown field")); + } } err.emit(); self.tcx().types.err diff --git a/src/test/compile-fail/attempted-access-non-fatal.rs b/src/test/compile-fail/attempted-access-non-fatal.rs index 1d9249bc17b1f..febe0bdd358f5 100644 --- a/src/test/compile-fail/attempted-access-non-fatal.rs +++ b/src/test/compile-fail/attempted-access-non-fatal.rs @@ -11,6 +11,8 @@ // Check that bogus field access is non-fatal fn main() { let x = 0; - let _ = x.foo; //~ ERROR attempted access of field - let _ = x.bar; //~ ERROR attempted access of field + let _ = x.foo; //~ ERROR no field `foo` on type + //~| NOTE unknown field + let _ = x.bar; //~ ERROR no field `bar` on type + //~| NOTE unknown field } diff --git a/src/test/compile-fail/cast-rfc0401.rs b/src/test/compile-fail/cast-rfc0401.rs index b6e81504a9d24..d7771f9c0f582 100644 --- a/src/test/compile-fail/cast-rfc0401.rs +++ b/src/test/compile-fail/cast-rfc0401.rs @@ -112,7 +112,8 @@ fn main() //~| NOTE required for the cast to the object type `Foo` // check no error cascade - let _ = main.f as *const u32; //~ ERROR attempted access of field + let _ = main.f as *const u32; //~ ERROR no field `f` on type `fn() {main}` + //~| NOTE unknown field let cf: *const Foo = &0; let _ = cf as *const [u16]; diff --git a/src/test/compile-fail/derived-errors/issue-30580.rs b/src/test/compile-fail/derived-errors/issue-30580.rs index 88d4aef6d9ddc..f194b2f27599f 100644 --- a/src/test/compile-fail/derived-errors/issue-30580.rs +++ b/src/test/compile-fail/derived-errors/issue-30580.rs @@ -19,7 +19,8 @@ impl<'a, 'tcx> Pass<'a, 'tcx> pub fn tcx(&self) -> &'a &'tcx () { self.1 } fn lol(&mut self, b: &Foo) { - b.c; //~ ERROR no field with that name was found + b.c; //~ ERROR no field `c` on type `&Foo` + //~| unknown field self.tcx(); } } diff --git a/src/test/compile-fail/issue-11004.rs b/src/test/compile-fail/issue-11004.rs index 308be46271531..ebb7f97506d37 100644 --- a/src/test/compile-fail/issue-11004.rs +++ b/src/test/compile-fail/issue-11004.rs @@ -14,9 +14,9 @@ struct A { x: i32, y: f64 } #[cfg(not(works))] unsafe fn access(n:*mut A) -> (i32, f64) { - let x : i32 = n.x; //~ ERROR attempted access of field `x` + let x : i32 = n.x; //~ ERROR no field `x` //~| NOTE `n` is a native pointer; perhaps you need to deref with `(*n).x` - let y : f64 = n.y; //~ ERROR attempted access of field `y` + let y : f64 = n.y; //~ ERROR no field `y` //~| NOTE `n` is a native pointer; perhaps you need to deref with `(*n).y` (x, y) } diff --git a/src/test/compile-fail/issue-14721.rs b/src/test/compile-fail/issue-14721.rs index 92add18f9413c..bc3f931d72f15 100644 --- a/src/test/compile-fail/issue-14721.rs +++ b/src/test/compile-fail/issue-14721.rs @@ -10,6 +10,5 @@ fn main() { let foo = "str"; - println!("{}", foo.desc); //~ ERROR attempted access of field `desc` on type `&str`, - // but no field with that name was found + println!("{}", foo.desc); //~ ERROR no field `desc` on type `&str` } diff --git a/src/test/compile-fail/issue-19244-2.rs b/src/test/compile-fail/issue-19244-2.rs index 7d7d7d7c8ce4d..0b904208d71bf 100644 --- a/src/test/compile-fail/issue-19244-2.rs +++ b/src/test/compile-fail/issue-19244-2.rs @@ -13,5 +13,5 @@ const STRUCT: MyStruct = MyStruct { field: 42 }; fn main() { let a: [isize; STRUCT.nonexistent_field]; - //~^ ERROR attempted access of field `nonexistent_field` + //~^ ERROR no field `nonexistent_field` } diff --git a/src/test/compile-fail/issue-23253.rs b/src/test/compile-fail/issue-23253.rs index e977cd135ab67..f250cb4b8ace6 100644 --- a/src/test/compile-fail/issue-23253.rs +++ b/src/test/compile-fail/issue-23253.rs @@ -12,5 +12,6 @@ enum Foo { Bar } fn main() { Foo::Bar.a; - //~^ ERROR: attempted access of field `a` on type `Foo`, but no field with that name was found + //~^ ERROR: no field `a` on type `Foo` + //~| NOTE unknown field } diff --git a/src/test/compile-fail/issue-24363.rs b/src/test/compile-fail/issue-24363.rs index 590c464371c06..d3ce838e3b294 100644 --- a/src/test/compile-fail/issue-24363.rs +++ b/src/test/compile-fail/issue-24363.rs @@ -9,7 +9,7 @@ // except according to those terms. fn main() { - 1.create_a_type_error[ //~ ERROR attempted access of field + 1.create_a_type_error[ //~ ERROR no field `create_a_type_error` ()+() //~ ERROR binary operation `+` cannot be applied // ^ ensure that we typeck the inner expression ^ ]; diff --git a/src/test/compile-fail/issue-24365.rs b/src/test/compile-fail/issue-24365.rs index a4df42a8c70f2..5ca21abc83900 100644 --- a/src/test/compile-fail/issue-24365.rs +++ b/src/test/compile-fail/issue-24365.rs @@ -17,13 +17,17 @@ pub enum Foo { } fn test(a: Foo) { - println!("{}", a.b); //~ ERROR attempted access of field + println!("{}", a.b); //~ ERROR no field `b` on type `Foo` + //~| NOTE unknown field + //~| NOTE in this expansion } fn main() { let x = Attribute::Code { attr_name_idx: 42, }; - let z = (&x).attr_name_idx; //~ ERROR attempted access of field - let y = x.attr_name_idx; //~ ERROR attempted access of field + let z = (&x).attr_name_idx; //~ ERROR no field `attr_name_idx` on type `&Attribute` + //~| NOTE unknown field + let y = x.attr_name_idx; //~ ERROR no field `attr_name_idx` on type `Attribute` + //~| NOTE unknown field } diff --git a/src/test/compile-fail/issue-31011.rs b/src/test/compile-fail/issue-31011.rs index b828b11030d71..323d2e94e803a 100644 --- a/src/test/compile-fail/issue-31011.rs +++ b/src/test/compile-fail/issue-31011.rs @@ -11,7 +11,8 @@ macro_rules! log { ( $ctx:expr, $( $args:expr),* ) => { if $ctx.trace { - //~^ ERROR attempted access of field `trace` on type `&T`, but no field with that name + //~^ ERROR no field `trace` on type `&T` + //~| NOTE unknown field println!( $( $args, )* ); } } diff --git a/src/test/compile-fail/issue-36164.rs b/src/test/compile-fail/issue-36164.rs new file mode 100644 index 0000000000000..2540ea6733f76 --- /dev/null +++ b/src/test/compile-fail/issue-36164.rs @@ -0,0 +1,27 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Foo { + bar: u8 +} + +struct Bar { +} + +fn main() { + let f = Foo { bar: 22 }; + f.xxx; + //~^ ERROR no field `xxx` on type `Foo` + //~| NOTE did you mean `bar`? + let g = Bar { }; + g.yyy; + //~^ ERROR no field `yyy` on type `Bar` + //~| NOTE unknown field +} diff --git a/src/test/compile-fail/no-type-for-node-ice.rs b/src/test/compile-fail/no-type-for-node-ice.rs index aab4db6eadfd6..0bbe2caddf670 100644 --- a/src/test/compile-fail/no-type-for-node-ice.rs +++ b/src/test/compile-fail/no-type-for-node-ice.rs @@ -11,5 +11,6 @@ // Related issues: #20401, #20506, #20614, #20752, #20829, #20846, #20885, #20886 fn main() { - "".homura[""]; //~ ERROR no field with that name was found + "".homura[""]; //~ ERROR no field `homura` + //~| NOTE unknown field } diff --git a/src/test/compile-fail/struct-fields-typo.rs b/src/test/compile-fail/struct-fields-typo.rs index c897dc55204b1..882a9879fc59a 100644 --- a/src/test/compile-fail/struct-fields-typo.rs +++ b/src/test/compile-fail/struct-fields-typo.rs @@ -18,7 +18,7 @@ fn main() { foo: 0, bar: 0.5, }; - let x = foo.baa;//~ ERROR attempted access of field `baa` on type `BuildData` - //~^ HELP did you mean `bar`? + let x = foo.baa;//~ ERROR no field `baa` on type `BuildData` + //~| NOTE did you mean `bar`? println!("{}", x); } diff --git a/src/test/compile-fail/struct-pat-derived-error.rs b/src/test/compile-fail/struct-pat-derived-error.rs index 4b65292340fa1..94c24c0260474 100644 --- a/src/test/compile-fail/struct-pat-derived-error.rs +++ b/src/test/compile-fail/struct-pat-derived-error.rs @@ -15,7 +15,7 @@ struct a { impl a { fn foo(&self) { - let a { x, y } = self.d; //~ ERROR attempted access of field `d` + let a { x, y } = self.d; //~ ERROR no field `d` //~^ ERROR struct `a` does not have a field named `x` //~^^ ERROR struct `a` does not have a field named `y` //~^^^ ERROR pattern does not mention field `b` diff --git a/src/test/compile-fail/union/union-suggest-field.rs b/src/test/compile-fail/union/union-suggest-field.rs index ce421428d883b..ae81fd84894f4 100644 --- a/src/test/compile-fail/union/union-suggest-field.rs +++ b/src/test/compile-fail/union/union-suggest-field.rs @@ -22,8 +22,8 @@ fn main() { let u = U { principle: 0 }; //~^ ERROR union `U` has no field named `principle` //~| NOTE field does not exist - did you mean `principal`? - let w = u.principial; //~ ERROR attempted access of field `principial` on type `U` - //~^ HELP did you mean `principal`? + let w = u.principial; //~ ERROR no field `principial` on type `U` + //~| NOTE did you mean `principal`? let y = u.calculate; //~ ERROR attempted to take value of method `calculate` on type `U` //~^ HELP maybe a `()` to call it is missing? diff --git a/src/test/compile-fail/unsafe-fn-autoderef.rs b/src/test/compile-fail/unsafe-fn-autoderef.rs index 97a7bf147105a..15b304c69baf5 100644 --- a/src/test/compile-fail/unsafe-fn-autoderef.rs +++ b/src/test/compile-fail/unsafe-fn-autoderef.rs @@ -26,7 +26,7 @@ fn f(p: *const Rec) -> isize { // are prohibited by various checks, such as that the enum is // instantiable and so forth). - return p.f; //~ ERROR attempted access of field `f` on type `*const Rec` + return p.f; //~ ERROR no field `f` on type `*const Rec` } fn main() { diff --git a/src/test/incremental/struct_change_field_name.rs b/src/test/incremental/struct_change_field_name.rs index c27294442e7a4..8f283f2d0fa03 100644 --- a/src/test/incremental/struct_change_field_name.rs +++ b/src/test/incremental/struct_change_field_name.rs @@ -39,13 +39,13 @@ pub fn use_X() -> u32 { let x: X = X { x: 22 }; //[cfail2]~^ ERROR struct `X` has no field named `x` x.x as u32 - //[cfail2]~^ ERROR attempted access of field `x` + //[cfail2]~^ ERROR no field `x` on type `X` } #[rustc_dirty(label="TypeckItemBody", cfg="cfail2")] pub fn use_EmbedX(embed: EmbedX) -> u32 { embed.x.x as u32 - //[cfail2]~^ ERROR attempted access of field `x` + //[cfail2]~^ ERROR no field `x` } #[rustc_clean(label="TypeckItemBody", cfg="cfail2")] diff --git a/src/test/ui/macros/macro-backtrace-invalid-internals.stderr b/src/test/ui/macros/macro-backtrace-invalid-internals.stderr index 82000a59bfb17..77248bbce1a0d 100644 --- a/src/test/ui/macros/macro-backtrace-invalid-internals.stderr +++ b/src/test/ui/macros/macro-backtrace-invalid-internals.stderr @@ -7,11 +7,11 @@ error: no method named `fake` found for type `{integer}` in the current scope 50 | fake_method_stmt!(); | -------------------- in this macro invocation -error: attempted access of field `fake` on type `{integer}`, but no field with that name was found - --> $DIR/macro-backtrace-invalid-internals.rs:21:11 +error: no field `fake` on type `{integer}` + --> $DIR/macro-backtrace-invalid-internals.rs:21:13 | 21 | 1.fake - | ^^^^^^ + | ^^^^ unknown field ... 51 | fake_field_stmt!(); | ------------------- in this macro invocation @@ -34,11 +34,11 @@ error: no method named `fake` found for type `{integer}` in the current scope 54 | let _ = fake_method_expr!(); | ------------------- in this macro invocation -error: attempted access of field `fake` on type `{integer}`, but no field with that name was found - --> $DIR/macro-backtrace-invalid-internals.rs:39:11 +error: no field `fake` on type `{integer}` + --> $DIR/macro-backtrace-invalid-internals.rs:39:13 | 39 | 1.fake - | ^^^^^^ + | ^^^^ unknown field ... 55 | let _ = fake_field_expr!(); | ------------------ in this macro invocation