https://gcc.gnu.org/g:f81ec04bfde4e771998b44dd5c685069d1229652

commit f81ec04bfde4e771998b44dd5c685069d1229652
Author: Philip Herron <herron.phi...@googlemail.com>
Date:   Thu Apr 17 13:50:55 2025 +0100

    gccrs: Fix ICE when handling case of unknown field in HIR::FieldAccess
    
    We were wrongly adding the assertion that this must not be an enum but
    this is a pointless assertion we only care that there are variant in the
    ADT and if the field exists in the first variant.
    
    Fixes Rust-GCC#3581
    
    gcc/rust/ChangeLog:
    
            * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): fix 
bad assertion
    
    gcc/testsuite/ChangeLog:
    
            * rust/compile/nonexistent-field.rs: fix bad error message
            * rust/compile/issue-3581-1.rs: New test.
            * rust/compile/issue-3581-2.rs: New test.
    
    Signed-off-by: Philip Herron <herron.phi...@googlemail.com>

Diff:
---
 gcc/rust/typecheck/rust-hir-type-check-expr.cc  | 18 ++++++++----------
 gcc/testsuite/rust/compile/issue-3581-1.rs      | 12 ++++++++++++
 gcc/testsuite/rust/compile/issue-3581-2.rs      |  9 +++++++++
 gcc/testsuite/rust/compile/nonexistent-field.rs |  2 +-
 4 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index b960e73abd92..115aba7047b6 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1142,27 +1142,25 @@ TypeCheckExpr::visit (HIR::FieldAccessExpr &expr)
   bool is_valid_type = struct_base->get_kind () == TyTy::TypeKind::ADT;
   if (!is_valid_type)
     {
-      rust_error_at (expr.get_locus (),
-                    "expected algebraic data type got: [%s]",
-                    struct_base->as_string ().c_str ());
+      rust_error_at (expr.get_locus (), "expected algebraic data type got %qs",
+                    struct_base->get_name ().c_str ());
       return;
     }
 
   TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (struct_base);
-  rust_assert (!adt->is_enum ());
-  rust_assert (adt->number_of_variants () == 1);
-
+  rust_assert (adt->number_of_variants () > 0);
   TyTy::VariantDef *vaiant = adt->get_variants ().at (0);
 
   TyTy::StructFieldType *lookup = nullptr;
   bool found = vaiant->lookup_field (expr.get_field_name ().as_string (),
                                     &lookup, nullptr);
-  if (!found)
+  if (!found || adt->is_enum ())
     {
-      rust_error_at (expr.get_locus (), ErrorCode::E0609,
-                    "no field %qs on type %qs",
+      rich_location r (line_table, expr.get_locus ());
+      r.add_range (expr.get_field_name ().get_locus ());
+      rust_error_at (r, ErrorCode::E0609, "no field %qs on type %qs",
                     expr.get_field_name ().as_string ().c_str (),
-                    adt->as_string ().c_str ());
+                    adt->get_name ().c_str ());
       return;
     }
 
diff --git a/gcc/testsuite/rust/compile/issue-3581-1.rs 
b/gcc/testsuite/rust/compile/issue-3581-1.rs
new file mode 100644
index 000000000000..eb2f5f033d50
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3581-1.rs
@@ -0,0 +1,12 @@
+enum Foo {
+    Bar,
+}
+
+struct Baz;
+
+fn main() {
+    Foo::Bar.a;
+    // { dg-error "no field .a. on type .Foo. .E0609." "" { target *-*-* } .-1 
}
+    Baz.a;
+    // { dg-error "no field .a. on type .Baz. .E0609." "" { target *-*-* } .-1 
}
+}
diff --git a/gcc/testsuite/rust/compile/issue-3581-2.rs 
b/gcc/testsuite/rust/compile/issue-3581-2.rs
new file mode 100644
index 000000000000..505978444652
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3581-2.rs
@@ -0,0 +1,9 @@
+enum A {
+    X { inner: i32 },
+    Y,
+}
+
+pub fn test() {
+    let _ = A::Y.inner;
+    // { dg-error "no field .inner. on type .A. .E0609." "" { target *-*-* } 
.-1 }
+}
diff --git a/gcc/testsuite/rust/compile/nonexistent-field.rs 
b/gcc/testsuite/rust/compile/nonexistent-field.rs
index e20c49d3ebf4..9bcfb2fe84fb 100644
--- a/gcc/testsuite/rust/compile/nonexistent-field.rs
+++ b/gcc/testsuite/rust/compile/nonexistent-field.rs
@@ -6,7 +6,7 @@ fn main() {
 
     let s = StructWithFields { x: 0 };
     s.foo;
-    // { dg-error "no field .foo. on type .StructWithFields.StructWithFields 
.x.u32... .E0609." "" { target *-*-* } .-1 }
+    // { dg-error "no field .foo. on type .StructWithFields. .E0609." "" { 
target *-*-* } .-1 }
 
     let numbers = (1, 2, 3);
     numbers.3;

Reply via email to