Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve error message and snippet for "did you mean x" #36798

Merged
merged 1 commit into from Oct 4, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 8 additions & 6 deletions src/librustc_typeck/check/mod.rs
Expand Up @@ -2959,18 +2959,20 @@ 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 \
Expand Down
4 changes: 2 additions & 2 deletions src/test/compile-fail/attempted-access-non-fatal.rs
Expand Up @@ -11,6 +11,6 @@
// 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; //~ no field `foo` on type `{integer}`
let _ = x.bar; //~ no field `bar` on type `{integer}`
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/cast-rfc0401.rs
Expand Up @@ -112,7 +112,7 @@ 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; //~ no field `f` on type `fn() {main}`

let cf: *const Foo = &0;
let _ = cf as *const [u16];
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/derived-errors/issue-30580.rs
Expand Up @@ -19,7 +19,7 @@ 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`
self.tcx();
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/test/compile-fail/issue-11004.rs
Expand Up @@ -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; //~ no field `x` on type `*mut A`
//~| 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; //~ no field `y` on type `*mut A`
//~| NOTE `n` is a native pointer; perhaps you need to deref with `(*n).y`
(x, y)
}
Expand Down
3 changes: 1 addition & 2 deletions src/test/compile-fail/issue-14721.rs
Expand Up @@ -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); //~ no field `desc` on type `&str`
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/issue-19244-2.rs
Expand Up @@ -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`
//~^ no field `nonexistent_field` on type `MyStruct`
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/issue-23253.rs
Expand Up @@ -12,5 +12,5 @@ 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
//~^ no field `a` on type `Foo`
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/issue-24363.rs
Expand Up @@ -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[ //~ no field `create_a_type_error` on type `{integer}`
()+() //~ ERROR binary operation `+` cannot be applied
// ^ ensure that we typeck the inner expression ^
];
Expand Down
6 changes: 3 additions & 3 deletions src/test/compile-fail/issue-24365.rs
Expand Up @@ -17,13 +17,13 @@ pub enum Foo {
}

fn test(a: Foo) {
println!("{}", a.b); //~ ERROR attempted access of field
println!("{}", a.b); //~ no field `b` on type `Foo`
}

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; //~ no field `attr_name_idx` on type `&Attribute`
let y = x.attr_name_idx; //~ no field `attr_name_idx` on type `Attribute`
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/issue-31011.rs
Expand Up @@ -11,7 +11,7 @@
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
//~^ no field `trace` on type `&T`
println!( $( $args, )* );
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/no-type-for-node-ice.rs
Expand Up @@ -11,5 +11,5 @@
// Related issues: #20401, #20506, #20614, #20752, #20829, #20846, #20885, #20886

fn main() {
"".homura[""]; //~ ERROR no field with that name was found
"".homura[""]; //~ no field `homura` on type `&'static str`
}
4 changes: 2 additions & 2 deletions src/test/compile-fail/struct-fields-typo.rs
Expand Up @@ -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;//~ no field `baa` on type `BuildData`
//~^ did you mean `bar`?
println!("{}", x);
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/struct-pat-derived-error.rs
Expand Up @@ -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` on type `&a`
//~^ 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`
Expand Down
4 changes: 2 additions & 2 deletions src/test/compile-fail/union/union-suggest-field.rs
Expand Up @@ -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`
//~^ 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?
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/unsafe-fn-autoderef.rs
Expand Up @@ -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() {
Expand Down
4 changes: 2 additions & 2 deletions src/test/incremental/struct_change_field_name.rs
Expand Up @@ -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` on type `X`
}

#[rustc_clean(label="TypeckItemBody", cfg="cfail2")]
Expand Down
18 changes: 18 additions & 0 deletions src/test/ui/did_you_mean/issue-36798.rs
@@ -0,0 +1,18 @@
// Copyright 2016 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

struct Foo {
bar: u8
}

fn main() {
let f = Foo { bar: 22 };
f.baz;
}
8 changes: 8 additions & 0 deletions src/test/ui/did_you_mean/issue-36798.stderr
@@ -0,0 +1,8 @@
error: no field `baz` on type `Foo`
--> $DIR/issue-36798.rs:17:7
|
17 | f.baz;
| ^^^ did you mean `bar`?

error: aborting due to previous error

18 changes: 18 additions & 0 deletions src/test/ui/did_you_mean/issue-36798_unknown_field.rs
@@ -0,0 +1,18 @@
// Copyright 2016 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

struct Foo {
bar: u8
}

fn main() {
let f = Foo { bar: 22 };
f.zz;
}
8 changes: 8 additions & 0 deletions src/test/ui/did_you_mean/issue-36798_unknown_field.stderr
@@ -0,0 +1,8 @@
error: no field `zz` on type `Foo`
--> $DIR/issue-36798_unknown_field.rs:17:7
|
17 | f.zz;
| ^^ unknown field

error: aborting due to previous error

12 changes: 6 additions & 6 deletions src/test/ui/macros/macro-backtrace-invalid-internals.stderr
Expand Up @@ -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
| ^^^^^^
| ^^^^
...
51 | fake_field_stmt!();
| ------------------- in this macro invocation
Expand All @@ -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
| ^^^^^^
| ^^^^
...
55 | let _ = fake_field_expr!();
| ------------------ in this macro invocation
Expand Down