From dfc326d0e212bd644d04906ca21bb012cf970cb4 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Thu, 20 Dec 2018 18:10:46 -0500 Subject: [PATCH] use structured suggestions for nonexistent fields --- src/librustc_typeck/check/mod.rs | 24 +++++++++++++------ src/test/ui/did_you_mean/issue-36798.stderr | 2 +- .../issue-42599_available_fields_note.stderr | 4 ++-- src/test/ui/error-codes/ex-E0612.stderr | 2 +- ...73-zero-padded-tuple-struct-indices.stderr | 2 +- src/test/ui/issues/issue-4736.stderr | 2 +- src/test/ui/issues/issue-56199.stderr | 8 +++---- src/test/ui/issues/issue-56835.stderr | 2 +- src/test/ui/rmeta_meta_main.stderr | 2 +- .../struct-fields-hints-no-dupe.stderr | 2 +- .../ui/structs/struct-fields-hints.stderr | 2 +- src/test/ui/structs/struct-fields-typo.rs | 5 ++-- src/test/ui/structs/struct-fields-typo.stderr | 4 ++-- .../suggestions/suggest-private-fields.stderr | 6 ++--- .../ui/tuple/tuple-index-not-tuple.stderr | 2 +- .../ui/tuple/tuple-index-out-of-bounds.stderr | 2 +- src/test/ui/union/union-suggest-field.rs | 6 ++++- src/test/ui/union/union-suggest-field.stderr | 8 +++---- 18 files changed, 50 insertions(+), 35 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 15a9ba99fa711..30c3dd51119c7 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -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, ); } } diff --git a/src/test/ui/did_you_mean/issue-36798.stderr b/src/test/ui/did_you_mean/issue-36798.stderr index 41dc15c1b81e7..8273fad476462 100644 --- a/src/test/ui/did_you_mean/issue-36798.stderr +++ b/src/test/ui/did_you_mean/issue-36798.stderr @@ -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 diff --git a/src/test/ui/did_you_mean/issue-42599_available_fields_note.stderr b/src/test/ui/did_you_mean/issue-42599_available_fields_note.stderr index 808ff1670da09..e5dd61c45d662 100644 --- a/src/test/ui/did_you_mean/issue-42599_available_fields_note.stderr +++ b/src/test/ui/did_you_mean/issue-42599_available_fields_note.stderr @@ -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 diff --git a/src/test/ui/error-codes/ex-E0612.stderr b/src/test/ui/error-codes/ex-E0612.stderr index e65e8bd814266..0f498d1643905 100644 --- a/src/test/ui/error-codes/ex-E0612.stderr +++ b/src/test/ui/error-codes/ex-E0612.stderr @@ -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 diff --git a/src/test/ui/issues/issue-47073-zero-padded-tuple-struct-indices.stderr b/src/test/ui/issues/issue-47073-zero-padded-tuple-struct-indices.stderr index 6e8d1ef2f7b9e..5e1b816defda3 100644 --- a/src/test/ui/issues/issue-47073-zero-padded-tuple-struct-indices.stderr +++ b/src/test/ui/issues/issue-47073-zero-padded-tuple-struct-indices.stderr @@ -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 diff --git a/src/test/ui/issues/issue-4736.stderr b/src/test/ui/issues/issue-4736.stderr index eac7e65064d49..39c649ba3e0e7 100644 --- a/src/test/ui/issues/issue-4736.stderr +++ b/src/test/ui/issues/issue-4736.stderr @@ -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` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-56199.stderr b/src/test/ui/issues/issue-56199.stderr index 9503183deb97c..7aaf8e4ac2f14 100644 --- a/src/test/ui/issues/issue-56199.stderr +++ b/src/test/ui/issues/issue-56199.stderr @@ -4,7 +4,7 @@ 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 @@ -12,19 +12,19 @@ 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: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 diff --git a/src/test/ui/issues/issue-56835.stderr b/src/test/ui/issues/issue-56835.stderr index 21ecbf05dc72f..f9fdf23af9715 100644 --- a/src/test/ui/issues/issue-56835.stderr +++ b/src/test/ui/issues/issue-56835.stderr @@ -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 diff --git a/src/test/ui/rmeta_meta_main.stderr b/src/test/ui/rmeta_meta_main.stderr index b7d7f89cfbb4c..bed9076d84cbe 100644 --- a/src/test/ui/rmeta_meta_main.stderr +++ b/src/test/ui/rmeta_meta_main.stderr @@ -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 diff --git a/src/test/ui/structs/struct-fields-hints-no-dupe.stderr b/src/test/ui/structs/struct-fields-hints-no-dupe.stderr index 105f330463a94..1a88f269347c2 100644 --- a/src/test/ui/structs/struct-fields-hints-no-dupe.stderr +++ b/src/test/ui/structs/struct-fields-hints-no-dupe.stderr @@ -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 diff --git a/src/test/ui/structs/struct-fields-hints.stderr b/src/test/ui/structs/struct-fields-hints.stderr index d713030563102..3b8a2b5c7bad0 100644 --- a/src/test/ui/structs/struct-fields-hints.stderr +++ b/src/test/ui/structs/struct-fields-hints.stderr @@ -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 diff --git a/src/test/ui/structs/struct-fields-typo.rs b/src/test/ui/structs/struct-fields-typo.rs index b435a0a47773d..0e9b2ae5145d7 100644 --- a/src/test/ui/structs/struct-fields-typo.rs +++ b/src/test/ui/structs/struct-fields-typo.rs @@ -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); } diff --git a/src/test/ui/structs/struct-fields-typo.stderr b/src/test/ui/structs/struct-fields-typo.stderr index 93127ab5beb6e..c2fab714f7c15 100644 --- a/src/test/ui/structs/struct-fields-typo.stderr +++ b/src/test/ui/structs/struct-fields-typo.stderr @@ -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 diff --git a/src/test/ui/suggestions/suggest-private-fields.stderr b/src/test/ui/suggestions/suggest-private-fields.stderr index 5f0176473ea74..524558e0ec564 100644 --- a/src/test/ui/suggestions/suggest-private-fields.stderr +++ b/src/test/ui/suggestions/suggest-private-fields.stderr @@ -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 diff --git a/src/test/ui/tuple/tuple-index-not-tuple.stderr b/src/test/ui/tuple/tuple-index-not-tuple.stderr index ab9ac4c4142fe..a1bcdfaedbc60 100644 --- a/src/test/ui/tuple/tuple-index-not-tuple.stderr +++ b/src/test/ui/tuple/tuple-index-not-tuple.stderr @@ -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 diff --git a/src/test/ui/tuple/tuple-index-out-of-bounds.stderr b/src/test/ui/tuple/tuple-index-out-of-bounds.stderr index 86e977a01b76d..7d7c5cd7892ea 100644 --- a/src/test/ui/tuple/tuple-index-out-of-bounds.stderr +++ b/src/test/ui/tuple/tuple-index-out-of-bounds.stderr @@ -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 diff --git a/src/test/ui/union/union-suggest-field.rs b/src/test/ui/union/union-suggest-field.rs index ad527a9791802..b2d8c0efea8fe 100644 --- a/src/test/ui/union/union-suggest-field.rs +++ b/src/test/ui/union/union-suggest-field.rs @@ -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 } diff --git a/src/test/ui/union/union-suggest-field.stderr b/src/test/ui/union/union-suggest-field.stderr index 15464eea4c2f3..91d6b30ea0267 100644 --- a/src/test/ui/union/union-suggest-field.stderr +++ b/src/test/ui/union/union-suggest-field.stderr @@ -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` | ^^^^^^^^^