diff options
author | Philip Herron <herron.philip@googlemail.com> | 2025-04-17 13:50:55 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2025-04-18 14:01:15 +0000 |
commit | f81ec04bfde4e771998b44dd5c685069d1229652 (patch) | |
tree | 9a976c3a47b4164cf555245a95577eb7c6c33bde /gcc | |
parent | 0a34f7bb91855ac95c51219c89d4049c4d69f7b3 (diff) | |
download | gcc-f81ec04bfde4e771998b44dd5c685069d1229652.zip gcc-f81ec04bfde4e771998b44dd5c685069d1229652.tar.gz gcc-f81ec04bfde4e771998b44dd5c685069d1229652.tar.bz2 |
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.philip@googlemail.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.cc | 18 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/issue-3581-1.rs | 12 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/issue-3581-2.rs | 9 | ||||
-rw-r--r-- | 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 b960e73..115aba7 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 0000000..eb2f5f0 --- /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 0000000..5059784 --- /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 e20c49d..9bcfb2f 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; |