about summary refs log tree commit diff
diff options
context:
space:
mode:
authorStuart Cook <Zalathar@users.noreply.github.com>2025-04-08 20:55:01 +1000
committerGitHub <noreply@github.com>2025-04-08 20:55:01 +1000
commit6257825c8fed1a5df762ca769abc876d40e70eef (patch)
treeb4a84b9a524e611446c43ee4c586c3f45a69fe4e
parent2b1afcbd1accd9e73c94029d3c420fa26b29676c (diff)
parent250b848272d24d79e815994053a4a690d92b7264 (diff)
downloadrust-6257825c8fed1a5df762ca769abc876d40e70eef.tar.gz
rust-6257825c8fed1a5df762ca769abc876d40e70eef.zip
Rollup merge of #139024 - compiler-errors:tweak-default-value-err, r=lcnr
Make error message for missing fields with `..` and without `..` more consistent

When `..` is not present, we say "missing field `bar` in initializer", but when it is present we say "missing mandatory field `bar`". I don't see why the primary error message should change, b/c the root cause is the same.

Let's harmonize these error messages and instead use a label to explain that `..` is required b/c it's not defaulted.

r? estebank
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs8
-rw-r--r--tests/ui/structs/default-field-values/failures.rs5
-rw-r--r--tests/ui/structs/default-field-values/failures.stderr26
3 files changed, 25 insertions, 14 deletions
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 952a2e231e4..3475d15e948 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -2205,8 +2205,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let fields = listify(&missing_mandatory_fields, |f| format!("`{f}`")).unwrap();
                 self.dcx()
                     .struct_span_err(
-                        span.shrink_to_hi(),
-                        format!("missing mandatory field{s} {fields}"),
+                        span.shrink_to_lo(),
+                        format!("missing field{s} {fields} in initializer"),
+                    )
+                    .with_span_label(
+                        span.shrink_to_lo(),
+                        "fields that do not have a defaulted value must be provided explicitly",
                     )
                     .emit();
                 return;
diff --git a/tests/ui/structs/default-field-values/failures.rs b/tests/ui/structs/default-field-values/failures.rs
index 1e94eecb4f8..4461302e841 100644
--- a/tests/ui/structs/default-field-values/failures.rs
+++ b/tests/ui/structs/default-field-values/failures.rs
@@ -1,4 +1,4 @@
-#![feature(default_field_values)]
+ #![feature(default_field_values)]
 
 #[derive(Debug)]
 pub struct S;
@@ -50,7 +50,8 @@ enum E {
 fn main () {
     let _ = Foo { .. }; // ok
     let _ = Foo::default(); // ok
-    let _ = Bar { .. }; //~ ERROR mandatory field
+    let _ = Bar { .. }; //~ ERROR missing field
+    let _ = Bar { baz: 0, .. }; //~ ERROR missing field
     let _ = Bar::default(); // silenced
     let _ = Bar { bar: S, .. }; // ok
     let _ = Qux::<4> { .. };
diff --git a/tests/ui/structs/default-field-values/failures.stderr b/tests/ui/structs/default-field-values/failures.stderr
index 58f7baee4b2..21c9bfb44b4 100644
--- a/tests/ui/structs/default-field-values/failures.stderr
+++ b/tests/ui/structs/default-field-values/failures.stderr
@@ -27,14 +27,20 @@ LL + #[derive(Default)]
 LL | pub struct S;
    |
 
-error: missing mandatory field `bar`
-  --> $DIR/failures.rs:53:21
+error: missing field `bar` in initializer
+  --> $DIR/failures.rs:53:19
    |
 LL |     let _ = Bar { .. };
-   |                     ^
+   |                   ^ fields that do not have a defaulted value must be provided explicitly
+
+error: missing field `bar` in initializer
+  --> $DIR/failures.rs:54:27
+   |
+LL |     let _ = Bar { baz: 0, .. };
+   |                           ^ fields that do not have a defaulted value must be provided explicitly
 
 error[E0308]: mismatched types
-  --> $DIR/failures.rs:57:17
+  --> $DIR/failures.rs:58:17
    |
 LL |     let _ = Rak(..);
    |             --- ^^ expected `i32`, found `RangeFull`
@@ -47,19 +53,19 @@ note: tuple struct defined here
 LL | pub struct Rak(i32 = 42);
    |            ^^^
 help: you might have meant to use `..` to skip providing a value for expected fields, but this is only supported on non-tuple struct literals; it is instead interpreted as a `std::ops::RangeFull` literal
-  --> $DIR/failures.rs:57:17
+  --> $DIR/failures.rs:58:17
    |
 LL |     let _ = Rak(..);
    |                 ^^
 
 error[E0061]: this struct takes 1 argument but 2 arguments were supplied
-  --> $DIR/failures.rs:59:13
+  --> $DIR/failures.rs:60:13
    |
 LL |     let _ = Rak(0, ..);
    |             ^^^    -- unexpected argument #2 of type `RangeFull`
    |
 help: you might have meant to use `..` to skip providing a value for expected fields, but this is only supported on non-tuple struct literals; it is instead interpreted as a `std::ops::RangeFull` literal
-  --> $DIR/failures.rs:59:20
+  --> $DIR/failures.rs:60:20
    |
 LL |     let _ = Rak(0, ..);
    |                    ^^
@@ -75,13 +81,13 @@ LL +     let _ = Rak(0);
    |
 
 error[E0061]: this struct takes 1 argument but 2 arguments were supplied
-  --> $DIR/failures.rs:61:13
+  --> $DIR/failures.rs:62:13
    |
 LL |     let _ = Rak(.., 0);
    |             ^^^ -- unexpected argument #1 of type `RangeFull`
    |
 help: you might have meant to use `..` to skip providing a value for expected fields, but this is only supported on non-tuple struct literals; it is instead interpreted as a `std::ops::RangeFull` literal
-  --> $DIR/failures.rs:61:17
+  --> $DIR/failures.rs:62:17
    |
 LL |     let _ = Rak(.., 0);
    |                 ^^
@@ -96,7 +102,7 @@ LL -     let _ = Rak(.., 0);
 LL +     let _ = Rak(0);
    |
 
-error: aborting due to 7 previous errors
+error: aborting due to 8 previous errors
 
 Some errors have detailed explanations: E0061, E0277, E0308.
 For more information about an error, try `rustc --explain E0061`.