about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOlaf Siwiński <olaf@olafes.com>2024-06-05 21:54:22 +0200
committerOlaf Siwiński <olaf@olafes.com>2024-06-05 21:54:22 +0200
commit743c41757c3211d989334b50b71df34279add5bb (patch)
treea8152534dec63abb1c95d1e6a1367d45c20ecd77
parentc1dba09f263cbff6170f130aa418e28bdf22bd96 (diff)
downloadrust-743c41757c3211d989334b50b71df34279add5bb.tar.gz
rust-743c41757c3211d989334b50b71df34279add5bb.zip
check_expr_struct_fields: taint context with errors if struct definition is malformed
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs9
-rw-r--r--tests/crashes/124552.rs12
-rw-r--r--tests/ui/static/duplicated-fields-issue-124464.rs (renamed from tests/crashes/124464.rs)6
-rw-r--r--tests/ui/static/duplicated-fields-issue-124464.stderr22
-rw-r--r--tests/ui/static/duplicated-fields-issue-125842.rs21
-rw-r--r--tests/ui/static/duplicated-fields-issue-125842.stderr11
6 files changed, 68 insertions, 13 deletions
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 4cc936eed08..7dd7b3ff055 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1671,6 +1671,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let mut error_happened = false;
 
+        if variant.fields.len() != remaining_fields.len() {
+            // Some field is defined more than once. Make sure we don't try to
+            // instantiate this struct in static/const context.
+            let guar =
+                self.dcx().span_delayed_bug(expr.span, "struct fields have non-unique names");
+            self.set_tainted_by_errors(guar);
+            error_happened = true;
+        }
+
         // Type-check each field.
         for (idx, field) in hir_fields.iter().enumerate() {
             let ident = tcx.adjust_ident(field.ident, variant.def_id);
diff --git a/tests/crashes/124552.rs b/tests/crashes/124552.rs
deleted file mode 100644
index 5320ce27843..00000000000
--- a/tests/crashes/124552.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-//@ known-bug: rust-lang/rust#124552
-
-struct B;
-
-struct Foo {
-    b: u32,
-    b: B,
-}
-
-static BAR: Foo = Foo { b: B };
-
-fn main() {}
diff --git a/tests/crashes/124464.rs b/tests/ui/static/duplicated-fields-issue-124464.rs
index 471479f5cf1..60609edbfeb 100644
--- a/tests/crashes/124464.rs
+++ b/tests/ui/static/duplicated-fields-issue-124464.rs
@@ -1,12 +1,16 @@
-//@ known-bug: rust-lang/rust #124464
+// Don't const eval fields with ambiguous layout.
+// See issues #125842 and #124464.
+
 enum TestOption<T> {
     TestSome(T),
     TestSome(T),
+//~^ ERROR the name `TestSome` is defined multiple times
 }
 
 pub struct Request {
     bar: TestOption<u64>,
     bar: u8,
+//~^ ERROR field `bar` is already declared
 }
 
 fn default_instance() -> &'static Request {
diff --git a/tests/ui/static/duplicated-fields-issue-124464.stderr b/tests/ui/static/duplicated-fields-issue-124464.stderr
new file mode 100644
index 00000000000..a36192ae8d6
--- /dev/null
+++ b/tests/ui/static/duplicated-fields-issue-124464.stderr
@@ -0,0 +1,22 @@
+error[E0428]: the name `TestSome` is defined multiple times
+  --> $DIR/duplicated-fields-issue-124464.rs:6:5
+   |
+LL |     TestSome(T),
+   |     ----------- previous definition of the type `TestSome` here
+LL |     TestSome(T),
+   |     ^^^^^^^^^^^ `TestSome` redefined here
+   |
+   = note: `TestSome` must be defined only once in the type namespace of this enum
+
+error[E0124]: field `bar` is already declared
+  --> $DIR/duplicated-fields-issue-124464.rs:12:5
+   |
+LL |     bar: TestOption<u64>,
+   |     -------------------- `bar` first declared here
+LL |     bar: u8,
+   |     ^^^^^^^ field already declared
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0124, E0428.
+For more information about an error, try `rustc --explain E0124`.
diff --git a/tests/ui/static/duplicated-fields-issue-125842.rs b/tests/ui/static/duplicated-fields-issue-125842.rs
new file mode 100644
index 00000000000..580b810232e
--- /dev/null
+++ b/tests/ui/static/duplicated-fields-issue-125842.rs
@@ -0,0 +1,21 @@
+// Do not try to evaluate static initalizers that reference
+// ill-defined types. This used to be an ICE.
+// See issues #125842 and #124464.
+struct Struct {
+    field: Option<u8>,
+    field: u8,
+//~^ ERROR field `field` is already declared
+}
+
+static STATIC_A: Struct = Struct {
+    field: 1
+};
+
+static STATIC_B: Struct = {
+    let field = 1;
+    Struct {
+        field,
+    }
+};
+
+fn main() {}
diff --git a/tests/ui/static/duplicated-fields-issue-125842.stderr b/tests/ui/static/duplicated-fields-issue-125842.stderr
new file mode 100644
index 00000000000..c80bb99005e
--- /dev/null
+++ b/tests/ui/static/duplicated-fields-issue-125842.stderr
@@ -0,0 +1,11 @@
+error[E0124]: field `field` is already declared
+  --> $DIR/duplicated-fields-issue-125842.rs:6:5
+   |
+LL |     field: Option<u8>,
+   |     ----------------- `field` first declared here
+LL |     field: u8,
+   |     ^^^^^^^^^ field already declared
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0124`.