Skip to content

use structured suggestions for nonexistent fields #57047

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

Merged
merged 1 commit into from
Dec 31, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
@@ -3415,8 +3415,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
if let Some(suggested_field_name) =
Self::suggest_field_name(def.non_enum_variant(),
&field.as_str(), vec![]) {
err.span_label(field.span,
format!("did you mean `{}`?", suggested_field_name));
err.span_suggestion_with_applicability(
field.span,
"a field with a similar name exists",
suggested_field_name.to_string(),
Applicability::MaybeIncorrect,
);
} else {
err.span_label(field.span, "unknown field");
let struct_variant_def = def.non_enum_variant();
@@ -3543,8 +3547,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
if let Some(field_name) = Self::suggest_field_name(variant,
&field.ident.as_str(),
skip_fields.collect()) {
err.span_label(field.ident.span,
format!("field does not exist - did you mean `{}`?", field_name));
err.span_suggestion_with_applicability(
field.ident.span,
"a field with a similar name exists",
field_name.to_string(),
Applicability::MaybeIncorrect,
);
} else {
match ty.sty {
ty::Adt(adt, ..) => {
@@ -5257,13 +5265,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
if let Some(adt_def) = adt_def {
match adt_def.adt_kind() {
AdtKind::Enum => {
err.note("did you mean to use one of the enum's variants?");
err.help("did you mean to use one of the enum's variants?");
},
AdtKind::Struct |
AdtKind::Union => {
err.span_label(
err.span_suggestion_with_applicability(
span,
format!("did you mean `Self {{ /* fields */ }}`?"),
"use curly brackets",
String::from("Self { /* fields */ }"),
Applicability::HasPlaceholders,
);
}
}
2 changes: 1 addition & 1 deletion src/test/ui/did_you_mean/issue-36798.stderr
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ error[E0609]: no field `baz` on type `Foo`
--> $DIR/issue-36798.rs:7:7
|
LL | f.baz; //~ ERROR no field
| ^^^ did you mean `bar`?
| ^^^ help: a field with a similar name exists: `bar`

error: aborting due to previous error

Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ error[E0560]: struct `submodule::Demo` has no field named `inocently_mispellable
--> $DIR/issue-42599_available_fields_note.rs:16:39
|
LL | Self { secret_integer: 2, inocently_mispellable: () }
| ^^^^^^^^^^^^^^^^^^^^^ field does not exist - did you mean `innocently_misspellable`?
| ^^^^^^^^^^^^^^^^^^^^^ help: a field with a similar name exists: `innocently_misspellable`

error[E0560]: struct `submodule::Demo` has no field named `egregiously_nonexistent_field`
--> $DIR/issue-42599_available_fields_note.rs:21:39
@@ -16,7 +16,7 @@ error[E0609]: no field `inocently_mispellable` on type `submodule::Demo`
--> $DIR/issue-42599_available_fields_note.rs:32:41
|
LL | let innocent_field_misaccess = demo.inocently_mispellable;
| ^^^^^^^^^^^^^^^^^^^^^ did you mean `innocently_misspellable`?
| ^^^^^^^^^^^^^^^^^^^^^ help: a field with a similar name exists: `innocently_misspellable`

error[E0609]: no field `egregiously_nonexistent_field` on type `submodule::Demo`
--> $DIR/issue-42599_available_fields_note.rs:35:42
2 changes: 1 addition & 1 deletion src/test/ui/error-codes/ex-E0612.stderr
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ error[E0609]: no field `1` on type `Foo`
--> $DIR/ex-E0612.rs:5:6
|
LL | y.1; //~ ERROR no field `1` on type `Foo`
| ^ did you mean `0`?
| ^ help: a field with a similar name exists: `0`

error: aborting due to previous error

Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ error[E0609]: no field `00` on type `Verdict`
--> $DIR/issue-47073-zero-padded-tuple-struct-indices.rs:8:30
|
LL | let _condemned = justice.00;
| ^^ did you mean `0`?
| ^^ help: a field with a similar name exists: `0`

error[E0609]: no field `001` on type `Verdict`
--> $DIR/issue-47073-zero-padded-tuple-struct-indices.rs:10:31
2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-4736.stderr
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ error[E0560]: struct `NonCopyable` has no field named `p`
--> $DIR/issue-4736.rs:4:26
|
LL | let z = NonCopyable{ p: () }; //~ ERROR struct `NonCopyable` has no field named `p`
| ^ field does not exist - did you mean `0`?
| ^ help: a field with a similar name exists: `0`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not relevant to this PR It'd be nice to suggest the appropriate syntax here:


error[E0560]: struct `NonCopyable` has no field named `p`
  --> $DIR/issue-4736.rs:4:26
   |
LL |     let z = NonCopyable{ p: () }; //~ ERROR struct `NonCopyable` has no field named `p`
   |             -------------^-----
   |             |            |
   |             |            field does not exist
   |             help: `NonCopyable` is a tuple struct, use the appropriate syntax: `NonCopyable(())`


error: aborting due to previous error

8 changes: 4 additions & 4 deletions src/test/ui/issues/issue-56199.stderr
Original file line number Diff line number Diff line change
@@ -4,27 +4,27 @@ error: the `Self` constructor can only be used with tuple or unit structs
LL | let _ = Self;
| ^^^^
|
= note: did you mean to use one of the enum's variants?
= help: did you mean to use one of the enum's variants?

error: the `Self` constructor can only be used with tuple or unit structs
--> $DIR/issue-56199.rs:8:17
|
LL | let _ = Self();
| ^^^^
|
= note: did you mean to use one of the enum's variants?
= help: did you mean to use one of the enum's variants?

error: the `Self` constructor can only be used with tuple or unit structs
--> $DIR/issue-56199.rs:15:17
|
LL | let _ = Self;
| ^^^^ did you mean `Self { /* fields */ }`?
| ^^^^ help: use curly brackets: `Self { /* fields */ }`

error: the `Self` constructor can only be used with tuple or unit structs
--> $DIR/issue-56199.rs:17:17
|
LL | let _ = Self();
| ^^^^ did you mean `Self { /* fields */ }`?
| ^^^^ help: use curly brackets: `Self { /* fields */ }`

error: aborting due to 4 previous errors

2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-56835.stderr
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ error: the `Self` constructor can only be used with tuple or unit structs
--> $DIR/issue-56835.rs:4:12
|
LL | fn bar(Self(foo): Self) {}
| ^^^^^^^^^ did you mean `Self { /* fields */ }`?
| ^^^^^^^^^ help: use curly brackets: `Self { /* fields */ }`

error[E0164]: expected tuple struct/variant, found self constructor `Self`
--> $DIR/issue-56835.rs:4:12
2 changes: 1 addition & 1 deletion src/test/ui/rmeta_meta_main.stderr
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ error[E0560]: struct `rmeta_meta::Foo` has no field named `field2`
--> $DIR/rmeta_meta_main.rs:13:19
|
LL | let _ = Foo { field2: 42 }; //~ ERROR struct `rmeta_meta::Foo` has no field named `field2`
| ^^^^^^ field does not exist - did you mean `field`?
| ^^^^^^ help: a field with a similar name exists: `field`

error: aborting due to previous error

2 changes: 1 addition & 1 deletion src/test/ui/structs/struct-fields-hints-no-dupe.stderr
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ error[E0560]: struct `A` has no field named `bar`
--> $DIR/struct-fields-hints-no-dupe.rs:10:9
|
LL | bar : 42,
| ^^^ field does not exist - did you mean `barr`?
| ^^^ help: a field with a similar name exists: `barr`

error: aborting due to previous error

2 changes: 1 addition & 1 deletion src/test/ui/structs/struct-fields-hints.stderr
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ error[E0560]: struct `A` has no field named `bar`
--> $DIR/struct-fields-hints.rs:10:9
|
LL | bar : 42,
| ^^^ field does not exist - did you mean `car`?
| ^^^ help: a field with a similar name exists: `car`

error: aborting due to previous error

5 changes: 3 additions & 2 deletions src/test/ui/structs/struct-fields-typo.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,8 @@ fn main() {
foo: 0,
bar: 0.5,
};
let x = foo.baa;//~ no field `baa` on type `BuildData`
//~^ did you mean `bar`?
let x = foo.baa; //~ ERROR no field `baa` on type `BuildData`
//~| HELP a field with a similar name exists
//~| SUGGESTION bar
println!("{}", x);
}
4 changes: 2 additions & 2 deletions src/test/ui/structs/struct-fields-typo.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0609]: no field `baa` on type `BuildData`
--> $DIR/struct-fields-typo.rs:11:17
|
LL | let x = foo.baa;//~ no field `baa` on type `BuildData`
| ^^^ did you mean `bar`?
LL | let x = foo.baa; //~ ERROR no field `baa` on type `BuildData`
| ^^^ help: a field with a similar name exists: `bar`

error: aborting due to previous error

6 changes: 3 additions & 3 deletions src/test/ui/suggestions/suggest-private-fields.stderr
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ error[E0560]: struct `xc::B` has no field named `aa`
--> $DIR/suggest-private-fields.rs:15:9
|
LL | aa: 20,
| ^^ field does not exist - did you mean `a`?
| ^^ help: a field with a similar name exists: `a`

error[E0560]: struct `xc::B` has no field named `bb`
--> $DIR/suggest-private-fields.rs:17:9
@@ -16,13 +16,13 @@ error[E0560]: struct `A` has no field named `aa`
--> $DIR/suggest-private-fields.rs:22:9
|
LL | aa: 20,
| ^^ field does not exist - did you mean `a`?
| ^^ help: a field with a similar name exists: `a`

error[E0560]: struct `A` has no field named `bb`
--> $DIR/suggest-private-fields.rs:24:9
|
LL | bb: 20,
| ^^ field does not exist - did you mean `b`?
| ^^ help: a field with a similar name exists: `b`

error: aborting due to 4 previous errors

2 changes: 1 addition & 1 deletion src/test/ui/tuple/tuple-index-not-tuple.stderr
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ error[E0609]: no field `0` on type `Point`
--> $DIR/tuple-index-not-tuple.rs:6:12
|
LL | origin.0;
| ^ did you mean `x`?
| ^ help: a field with a similar name exists: `x`

error[E0609]: no field `0` on type `Empty`
--> $DIR/tuple-index-not-tuple.rs:8:11
2 changes: 1 addition & 1 deletion src/test/ui/tuple/tuple-index-out-of-bounds.stderr
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ error[E0609]: no field `2` on type `Point`
--> $DIR/tuple-index-out-of-bounds.rs:7:12
|
LL | origin.2;
| ^ did you mean `0`?
| ^ help: a field with a similar name exists: `0`

error[E0609]: no field `2` on type `({integer}, {integer})`
--> $DIR/tuple-index-out-of-bounds.rs:12:11
6 changes: 5 additions & 1 deletion src/test/ui/union/union-suggest-field.rs
Original file line number Diff line number Diff line change
@@ -9,8 +9,12 @@ impl U {
fn main() {
let u = U { principle: 0 };
//~^ ERROR union `U` has no field named `principle`
//~| HELP a field with a similar name exists
//~| SUGGESTION principal
let w = u.principial; //~ ERROR no field `principial` on type `U`
//~^ did you mean `principal`?
//~| HELP a field with a similar name exists
//~| SUGGESTION principal

let y = u.calculate; //~ ERROR attempted to take value of method `calculate` on type `U`
//~| HELP maybe a `()` to call it is missing
}
8 changes: 4 additions & 4 deletions src/test/ui/union/union-suggest-field.stderr
Original file line number Diff line number Diff line change
@@ -2,16 +2,16 @@ error[E0560]: union `U` has no field named `principle`
--> $DIR/union-suggest-field.rs:10:17
|
LL | let u = U { principle: 0 };
| ^^^^^^^^^ field does not exist - did you mean `principal`?
| ^^^^^^^^^ help: a field with a similar name exists: `principal`

error[E0609]: no field `principial` on type `U`
--> $DIR/union-suggest-field.rs:12:15
--> $DIR/union-suggest-field.rs:14:15
|
LL | let w = u.principial; //~ ERROR no field `principial` on type `U`
| ^^^^^^^^^^ did you mean `principal`?
| ^^^^^^^^^^ help: a field with a similar name exists: `principal`

error[E0615]: attempted to take value of method `calculate` on type `U`
--> $DIR/union-suggest-field.rs:15:15
--> $DIR/union-suggest-field.rs:18:15
|
LL | let y = u.calculate; //~ ERROR attempted to take value of method `calculate` on type `U`
| ^^^^^^^^^