https://gcc.gnu.org/g:f8db3d9809aed048f0403668815375d2778da6ba
commit r17-2252-gf8db3d9809aed048f0403668815375d2778da6ba Author: João Novo <[email protected]> Date: Tue Mar 31 16:05:03 2026 +0100 gccrs: rust: Fix ICE with infer type used in struct attribute When visiting a struct declaration, add check for when a struct's attribute is declared as an infer type, emitting an error if true. Fixes Rust-GCC#3583 gcc/rust/ChangeLog: * typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): Add check for infer type on struct's attribute or its subtypes. * typecheck/rust-tyty.cc (BaseType::contains_infer): Add check for an array type's capacity being an infer type. gcc/testsuite/ChangeLog: * rust/compile/infer-type-issue-3583.rs: New test. Signed-off-by: João Novo <[email protected]> Diff: --- gcc/rust/typecheck/rust-hir-type-check-item.cc | 9 +++++++++ gcc/rust/typecheck/rust-tyty.cc | 12 ++++++++++- .../rust/compile/infer-type-issue-3583.rs | 23 ++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc b/gcc/rust/typecheck/rust-hir-type-check-item.cc index 8c8d7e416147..055ce2b2832b 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-item.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc @@ -325,6 +325,7 @@ void TypeCheckItem::visit (HIR::StructStruct &struct_decl) { auto lifetime_pin = context->push_clean_lifetime_resolver (); + auto &mappings = Analysis::Mappings::get (); std::vector<TyTy::SubstitutionParamMapping> substitutions; if (struct_decl.has_generics ()) @@ -343,6 +344,14 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl) { TyTy::BaseType *field_type = TypeCheckType::Resolve (field.get_field_type ()); + auto infer_type = field_type->contains_infer (); + if (infer_type) + { + rust_error_at (mappings.lookup_location (infer_type->get_ref ()), + "the placeholder %<_%> is not allowed within types on " + "item signatures for structs"); + return; + } auto *ty_field = new TyTy::StructFieldType (field.get_mappings ().get_hirid (), field.get_field_name ().as_string (), diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index 66f5fc5cb2c9..d5ef3b063b41 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -763,7 +763,10 @@ BaseType::contains_infer () const } else if (auto arr = x->try_as<const ArrayType> ()) { - return arr->get_element_type ()->contains_infer (); + auto type_infer = (arr->get_element_type ()->contains_infer ()); + if (type_infer) + return type_infer; + return arr->get_capacity ()->contains_infer (); } else if (auto slice = x->try_as<const SliceType> ()) { @@ -798,6 +801,13 @@ BaseType::contains_infer () const { return x; } + else if (x->get_kind () == TyTy::TypeKind::CONST) + { + if (x->as_const_type ()->const_kind () == BaseConstType::Infer) + { + return x; + } + } return nullptr; } diff --git a/gcc/testsuite/rust/compile/infer-type-issue-3583.rs b/gcc/testsuite/rust/compile/infer-type-issue-3583.rs new file mode 100644 index 000000000000..ab4d309672b5 --- /dev/null +++ b/gcc/testsuite/rust/compile/infer-type-issue-3583.rs @@ -0,0 +1,23 @@ +#![feature(no_core)] +#![no_core] + +struct Test10 { + a: _, // { dg-error "the placeholder ... is not allowed within types on item" } +} + +struct Test11 { + a: _, // { dg-error "the placeholder ... is not allowed within types on item" } + b: i32, +} + +struct Test12 { + a: (_, _), // { dg-error "the placeholder ... is not allowed within types on item" } +} + +struct Test13 { + a: [_; _], // { dg-error "the placeholder ... is not allowed within types on item" } +} + +struct Test14 { + a: [i32; _], // { dg-error "the placeholder ... is not allowed within types on item" } +}
