From 447ce2719810f7654bb3e5a3d20fb459bb191547 Mon Sep 17 00:00:00 2001 From: r00ster91 Date: Sat, 20 Feb 2021 18:32:02 +0100 Subject: [PATCH] Make "missing field" error message more natural --- compiler/rustc_typeck/src/check/expr.rs | 31 ++++++++++--------- src/test/ui/error-codes/E0063.rs | 2 +- src/test/ui/error-codes/E0063.stderr | 4 +-- src/test/ui/issues/issue-79593.rs | 2 +- src/test/ui/issues/issue-79593.stderr | 4 +-- src/test/ui/parser/issue-52496.rs | 2 +- src/test/ui/parser/issue-52496.stderr | 4 +-- .../parser/struct-field-numeric-shorthand.rs | 2 +- .../struct-field-numeric-shorthand.stderr | 4 +-- 9 files changed, 29 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index fa09c26c800ae..58cab950b2892 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -1348,7 +1348,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, remaining_fields: FxHashMap, ) { - let tcx = self.tcx; let len = remaining_fields.len(); let mut displayable_field_names = @@ -1356,25 +1355,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { displayable_field_names.sort(); - let truncated_fields_error = if len <= 3 { - String::new() - } else { - format!(" and {} other field{}", (len - 3), if len - 3 == 1 { "" } else { "s" }) + let mut truncated_fields_error = String::new(); + let remaining_fields_names = match &displayable_field_names[..] { + [field1] => format!("`{}`", field1), + [field1, field2] => format!("`{}` and `{}`", field1, field2), + [field1, field2, field3] => format!("`{}`, `{}` and `{}`", field1, field2, field3), + _ => { + truncated_fields_error = + format!(" and {} other field{}", len - 3, pluralize!(len - 3)); + displayable_field_names + .iter() + .take(3) + .map(|n| format!("`{}`", n)) + .collect::>() + .join(", ") + } }; - let remaining_fields_names = displayable_field_names - .iter() - .take(3) - .map(|n| format!("`{}`", n)) - .collect::>() - .join(", "); - struct_span_err!( - tcx.sess, + self.tcx.sess, span, E0063, "missing field{} {}{} in initializer of `{}`", - pluralize!(remaining_fields.len()), + pluralize!(len), remaining_fields_names, truncated_fields_error, adt_ty diff --git a/src/test/ui/error-codes/E0063.rs b/src/test/ui/error-codes/E0063.rs index 37fc0a2987d3f..58527cc0c5dd7 100644 --- a/src/test/ui/error-codes/E0063.rs +++ b/src/test/ui/error-codes/E0063.rs @@ -32,7 +32,7 @@ fn main() { let w = SingleFoo { }; //~^ ERROR missing field `x` in initializer of `SingleFoo` let x = PluralFoo {x: 1}; - //~^ ERROR missing fields `y`, `z` in initializer of `PluralFoo` + //~^ ERROR missing fields `y` and `z` in initializer of `PluralFoo` let y = TruncatedFoo{x:1}; //~^ missing fields `a`, `b`, `y` and 1 other field in initializer of `TruncatedFoo` let z = TruncatedPluralFoo{x:1}; diff --git a/src/test/ui/error-codes/E0063.stderr b/src/test/ui/error-codes/E0063.stderr index 5d366e0c1c47d..5dc4927071b6b 100644 --- a/src/test/ui/error-codes/E0063.stderr +++ b/src/test/ui/error-codes/E0063.stderr @@ -4,11 +4,11 @@ error[E0063]: missing field `x` in initializer of `SingleFoo` LL | let w = SingleFoo { }; | ^^^^^^^^^ missing `x` -error[E0063]: missing fields `y`, `z` in initializer of `PluralFoo` +error[E0063]: missing fields `y` and `z` in initializer of `PluralFoo` --> $DIR/E0063.rs:34:13 | LL | let x = PluralFoo {x: 1}; - | ^^^^^^^^^ missing `y`, `z` + | ^^^^^^^^^ missing `y` and `z` error[E0063]: missing fields `a`, `b`, `y` and 1 other field in initializer of `TruncatedFoo` --> $DIR/E0063.rs:36:13 diff --git a/src/test/ui/issues/issue-79593.rs b/src/test/ui/issues/issue-79593.rs index fb54b36940d51..b94278bfdd221 100644 --- a/src/test/ui/issues/issue-79593.rs +++ b/src/test/ui/issues/issue-79593.rs @@ -23,7 +23,7 @@ fn wrong() { foo::Enum::Variant { x: () }; //~^ ERROR missing field `y` in initializer of `Enum` foo::Enum::Variant { }; - //~^ ERROR missing fields `x`, `y` in initializer of `Enum` + //~^ ERROR missing fields `x` and `y` in initializer of `Enum` } fn main() {} diff --git a/src/test/ui/issues/issue-79593.stderr b/src/test/ui/issues/issue-79593.stderr index 33dbd85032eab..b8c7d4f23a28f 100644 --- a/src/test/ui/issues/issue-79593.stderr +++ b/src/test/ui/issues/issue-79593.stderr @@ -22,11 +22,11 @@ error[E0063]: missing field `y` in initializer of `Enum` LL | foo::Enum::Variant { x: () }; | ^^^^^^^^^^^^^^^^^^ missing `y` -error[E0063]: missing fields `x`, `y` in initializer of `Enum` +error[E0063]: missing fields `x` and `y` in initializer of `Enum` --> $DIR/issue-79593.rs:25:5 | LL | foo::Enum::Variant { }; - | ^^^^^^^^^^^^^^^^^^ missing `x`, `y` + | ^^^^^^^^^^^^^^^^^^ missing `x` and `y` error: aborting due to 5 previous errors diff --git a/src/test/ui/parser/issue-52496.rs b/src/test/ui/parser/issue-52496.rs index 4e9453653735a..05461f8b8c413 100644 --- a/src/test/ui/parser/issue-52496.rs +++ b/src/test/ui/parser/issue-52496.rs @@ -7,6 +7,6 @@ fn main() { let bar = 1.5f32; let _ = Foo { bar.into(), bat: -1, . }; //~^ ERROR expected one of - //~| ERROR missing fields `bar`, `baz` in initializer of `Foo` + //~| ERROR missing fields `bar` and `baz` in initializer of `Foo` //~| ERROR expected identifier, found `.` } diff --git a/src/test/ui/parser/issue-52496.stderr b/src/test/ui/parser/issue-52496.stderr index 10fcc46f344eb..9dbf26ef4b68c 100644 --- a/src/test/ui/parser/issue-52496.stderr +++ b/src/test/ui/parser/issue-52496.stderr @@ -26,11 +26,11 @@ error[E0063]: missing field `bat` in initializer of `Foo` LL | let _ = Foo { bar: .5, baz: 42 }; | ^^^ missing `bat` -error[E0063]: missing fields `bar`, `baz` in initializer of `Foo` +error[E0063]: missing fields `bar` and `baz` in initializer of `Foo` --> $DIR/issue-52496.rs:8:13 | LL | let _ = Foo { bar.into(), bat: -1, . }; - | ^^^ missing `bar`, `baz` + | ^^^ missing `bar` and `baz` error: aborting due to 5 previous errors diff --git a/src/test/ui/parser/struct-field-numeric-shorthand.rs b/src/test/ui/parser/struct-field-numeric-shorthand.rs index 58c40b3d96a49..645abd9c7192d 100644 --- a/src/test/ui/parser/struct-field-numeric-shorthand.rs +++ b/src/test/ui/parser/struct-field-numeric-shorthand.rs @@ -5,5 +5,5 @@ fn main() { //~^ ERROR expected identifier, found `0` //~| ERROR expected identifier, found `1` //~| ERROR expected identifier, found `2` - //~| ERROR missing fields `0`, `1`, `2` in initializer of `Rgb` + //~| ERROR missing fields `0`, `1` and `2` in initializer of `Rgb` } diff --git a/src/test/ui/parser/struct-field-numeric-shorthand.stderr b/src/test/ui/parser/struct-field-numeric-shorthand.stderr index cfb1f82014754..bfb8a931b6406 100644 --- a/src/test/ui/parser/struct-field-numeric-shorthand.stderr +++ b/src/test/ui/parser/struct-field-numeric-shorthand.stderr @@ -22,11 +22,11 @@ LL | let _ = Rgb { 0, 1, 2 }; | | | while parsing this struct -error[E0063]: missing fields `0`, `1`, `2` in initializer of `Rgb` +error[E0063]: missing fields `0`, `1` and `2` in initializer of `Rgb` --> $DIR/struct-field-numeric-shorthand.rs:4:13 | LL | let _ = Rgb { 0, 1, 2 }; - | ^^^ missing `0`, `1`, `2` + | ^^^ missing `0`, `1` and `2` error: aborting due to 4 previous errors