Skip to content

Commit 5a4ecb4

Browse files
authored
Rollup merge of rust-lang#36798 - gavinb:fix/36164, r=GuillaumeGomez
Improve error message and snippet for "did you mean `x`" - Fixes rust-lang#36164 - Part of rust-lang#35233 Based on the standalone example https://is.gd/8STXMd posted by @nikomatsakis and using the third formatting option mentioned in rust-lang#36164 and agreed by @jonathandturner. Note however this does not address the question of [how to handle an empty or unknown suggestion](rust-lang#36164 (comment)). @nikomatsakis any suggestions on how best to address that part?
2 parents 9c31d76 + 99aae9b commit 5a4ecb4

22 files changed

+89
-36
lines changed

src/librustc_typeck/check/mod.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -2959,18 +2959,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
29592959
.emit();
29602960
self.tcx().types.err
29612961
} else {
2962-
let mut err = self.type_error_struct(expr.span, |actual| {
2963-
format!("attempted access of field `{}` on type `{}`, \
2964-
but no field with that name was found",
2962+
let mut err = self.type_error_struct(field.span, |actual| {
2963+
format!("no field `{}` on type `{}`",
29652964
field.node, actual)
29662965
}, expr_t);
29672966
match expr_t.sty {
29682967
ty::TyAdt(def, _) if !def.is_enum() => {
29692968
if let Some(suggested_field_name) =
29702969
Self::suggest_field_name(def.struct_variant(), field, vec![]) {
2971-
err.span_help(field.span,
2972-
&format!("did you mean `{}`?", suggested_field_name));
2973-
};
2970+
err.span_label(field.span,
2971+
&format!("did you mean `{}`?", suggested_field_name));
2972+
} else {
2973+
err.span_label(field.span,
2974+
&format!("unknown field"));
2975+
};
29742976
}
29752977
ty::TyRawPtr(..) => {
29762978
err.note(&format!("`{0}` is a native pointer; perhaps you need to deref with \

src/test/compile-fail/attempted-access-non-fatal.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@
1111
// Check that bogus field access is non-fatal
1212
fn main() {
1313
let x = 0;
14-
let _ = x.foo; //~ ERROR attempted access of field
15-
let _ = x.bar; //~ ERROR attempted access of field
14+
let _ = x.foo; //~ no field `foo` on type `{integer}`
15+
let _ = x.bar; //~ no field `bar` on type `{integer}`
1616
}

src/test/compile-fail/cast-rfc0401.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ fn main()
112112
//~| NOTE required for the cast to the object type `Foo`
113113

114114
// check no error cascade
115-
let _ = main.f as *const u32; //~ ERROR attempted access of field
115+
let _ = main.f as *const u32; //~ no field `f` on type `fn() {main}`
116116

117117
let cf: *const Foo = &0;
118118
let _ = cf as *const [u16];

src/test/compile-fail/derived-errors/issue-30580.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ impl<'a, 'tcx> Pass<'a, 'tcx>
1919
pub fn tcx(&self) -> &'a &'tcx () { self.1 }
2020
fn lol(&mut self, b: &Foo)
2121
{
22-
b.c; //~ ERROR no field with that name was found
22+
b.c; //~ ERROR no field `c` on type `&Foo`
2323
self.tcx();
2424
}
2525
}

src/test/compile-fail/issue-11004.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ struct A { x: i32, y: f64 }
1414

1515
#[cfg(not(works))]
1616
unsafe fn access(n:*mut A) -> (i32, f64) {
17-
let x : i32 = n.x; //~ ERROR attempted access of field `x`
17+
let x : i32 = n.x; //~ no field `x` on type `*mut A`
1818
//~| NOTE `n` is a native pointer; perhaps you need to deref with `(*n).x`
19-
let y : f64 = n.y; //~ ERROR attempted access of field `y`
19+
let y : f64 = n.y; //~ no field `y` on type `*mut A`
2020
//~| NOTE `n` is a native pointer; perhaps you need to deref with `(*n).y`
2121
(x, y)
2222
}

src/test/compile-fail/issue-14721.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,5 @@
1010

1111
fn main() {
1212
let foo = "str";
13-
println!("{}", foo.desc); //~ ERROR attempted access of field `desc` on type `&str`,
14-
// but no field with that name was found
13+
println!("{}", foo.desc); //~ no field `desc` on type `&str`
1514
}

src/test/compile-fail/issue-19244-2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ const STRUCT: MyStruct = MyStruct { field: 42 };
1313

1414
fn main() {
1515
let a: [isize; STRUCT.nonexistent_field];
16-
//~^ ERROR attempted access of field `nonexistent_field`
16+
//~^ no field `nonexistent_field` on type `MyStruct`
1717
}

src/test/compile-fail/issue-23253.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ enum Foo { Bar }
1212

1313
fn main() {
1414
Foo::Bar.a;
15-
//~^ ERROR: attempted access of field `a` on type `Foo`, but no field with that name was found
15+
//~^ no field `a` on type `Foo`
1616
}

src/test/compile-fail/issue-24363.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// except according to those terms.
1010

1111
fn main() {
12-
1.create_a_type_error[ //~ ERROR attempted access of field
12+
1.create_a_type_error[ //~ no field `create_a_type_error` on type `{integer}`
1313
()+() //~ ERROR binary operation `+` cannot be applied
1414
// ^ ensure that we typeck the inner expression ^
1515
];

src/test/compile-fail/issue-24365.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ pub enum Foo {
1717
}
1818

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

2323
fn main() {
2424
let x = Attribute::Code {
2525
attr_name_idx: 42,
2626
};
27-
let z = (&x).attr_name_idx; //~ ERROR attempted access of field
28-
let y = x.attr_name_idx; //~ ERROR attempted access of field
27+
let z = (&x).attr_name_idx; //~ no field `attr_name_idx` on type `&Attribute`
28+
let y = x.attr_name_idx; //~ no field `attr_name_idx` on type `Attribute`
2929
}

src/test/compile-fail/issue-31011.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
macro_rules! log {
1212
( $ctx:expr, $( $args:expr),* ) => {
1313
if $ctx.trace {
14-
//~^ ERROR attempted access of field `trace` on type `&T`, but no field with that name
14+
//~^ no field `trace` on type `&T`
1515
println!( $( $args, )* );
1616
}
1717
}

src/test/compile-fail/no-type-for-node-ice.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@
1111
// Related issues: #20401, #20506, #20614, #20752, #20829, #20846, #20885, #20886
1212

1313
fn main() {
14-
"".homura[""]; //~ ERROR no field with that name was found
14+
"".homura[""]; //~ no field `homura` on type `&'static str`
1515
}

src/test/compile-fail/struct-fields-typo.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ fn main() {
1818
foo: 0,
1919
bar: 0.5,
2020
};
21-
let x = foo.baa;//~ ERROR attempted access of field `baa` on type `BuildData`
22-
//~^ HELP did you mean `bar`?
21+
let x = foo.baa;//~ no field `baa` on type `BuildData`
22+
//~^ did you mean `bar`?
2323
println!("{}", x);
2424
}

src/test/compile-fail/struct-pat-derived-error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ struct a {
1515

1616
impl a {
1717
fn foo(&self) {
18-
let a { x, y } = self.d; //~ ERROR attempted access of field `d`
18+
let a { x, y } = self.d; //~ ERROR no field `d` on type `&a`
1919
//~^ ERROR struct `a` does not have a field named `x`
2020
//~^^ ERROR struct `a` does not have a field named `y`
2121
//~^^^ ERROR pattern does not mention field `b`

src/test/compile-fail/union/union-suggest-field.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ fn main() {
2222
let u = U { principle: 0 };
2323
//~^ ERROR union `U` has no field named `principle`
2424
//~| NOTE field does not exist - did you mean `principal`?
25-
let w = u.principial; //~ ERROR attempted access of field `principial` on type `U`
26-
//~^ HELP did you mean `principal`?
25+
let w = u.principial; //~ ERROR no field `principial` on type `U`
26+
//~^ did you mean `principal`?
2727

2828
let y = u.calculate; //~ ERROR attempted to take value of method `calculate` on type `U`
2929
//~^ HELP maybe a `()` to call it is missing?

src/test/compile-fail/unsafe-fn-autoderef.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ fn f(p: *const Rec) -> isize {
2626
// are prohibited by various checks, such as that the enum is
2727
// instantiable and so forth).
2828

29-
return p.f; //~ ERROR attempted access of field `f` on type `*const Rec`
29+
return p.f; //~ ERROR no field `f` on type `*const Rec`
3030
}
3131

3232
fn main() {

src/test/incremental/struct_change_field_name.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ pub fn use_X() -> u32 {
3939
let x: X = X { x: 22 };
4040
//[cfail2]~^ ERROR struct `X` has no field named `x`
4141
x.x as u32
42-
//[cfail2]~^ ERROR attempted access of field `x`
42+
//[cfail2]~^ ERROR no field `x` on type `X`
4343
}
4444

4545
#[rustc_dirty(label="TypeckItemBody", cfg="cfail2")]
4646
pub fn use_EmbedX(embed: EmbedX) -> u32 {
4747
embed.x.x as u32
48-
//[cfail2]~^ ERROR attempted access of field `x`
48+
//[cfail2]~^ ERROR no field `x` on type `X`
4949
}
5050

5151
#[rustc_clean(label="TypeckItemBody", cfg="cfail2")]
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
struct Foo {
12+
bar: u8
13+
}
14+
15+
fn main() {
16+
let f = Foo { bar: 22 };
17+
f.baz;
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: no field `baz` on type `Foo`
2+
--> $DIR/issue-36798.rs:17:7
3+
|
4+
17 | f.baz;
5+
| ^^^ did you mean `bar`?
6+
7+
error: aborting due to previous error
8+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
struct Foo {
12+
bar: u8
13+
}
14+
15+
fn main() {
16+
let f = Foo { bar: 22 };
17+
f.zz;
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: no field `zz` on type `Foo`
2+
--> $DIR/issue-36798_unknown_field.rs:17:7
3+
|
4+
17 | f.zz;
5+
| ^^ unknown field
6+
7+
error: aborting due to previous error
8+

src/test/ui/macros/macro-backtrace-invalid-internals.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ error: no method named `fake` found for type `{integer}` in the current scope
77
50 | fake_method_stmt!();
88
| -------------------- in this macro invocation
99

10-
error: attempted access of field `fake` on type `{integer}`, but no field with that name was found
11-
--> $DIR/macro-backtrace-invalid-internals.rs:21:11
10+
error: no field `fake` on type `{integer}`
11+
--> $DIR/macro-backtrace-invalid-internals.rs:21:13
1212
|
1313
21 | 1.fake
14-
| ^^^^^^
14+
| ^^^^
1515
...
1616
51 | fake_field_stmt!();
1717
| ------------------- in this macro invocation
@@ -34,11 +34,11 @@ error: no method named `fake` found for type `{integer}` in the current scope
3434
54 | let _ = fake_method_expr!();
3535
| ------------------- in this macro invocation
3636

37-
error: attempted access of field `fake` on type `{integer}`, but no field with that name was found
38-
--> $DIR/macro-backtrace-invalid-internals.rs:39:11
37+
error: no field `fake` on type `{integer}`
38+
--> $DIR/macro-backtrace-invalid-internals.rs:39:13
3939
|
4040
39 | 1.fake
41-
| ^^^^^^
41+
| ^^^^
4242
...
4343
55 | let _ = fake_field_expr!();
4444
| ------------------ in this macro invocation

0 commit comments

Comments
 (0)