]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: rust: Fix ICE with infer type used in struct attribute
authorJoão Novo <joao.c.novo@tecnico.ulisboa.pt>
Tue, 31 Mar 2026 15:05:03 +0000 (16:05 +0100)
committerArthur Cohen <arthur.cohen@embecosm.com>
Wed, 8 Jul 2026 15:22:52 +0000 (17:22 +0200)
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 <joao.c.novo@tecnico.ulisboa.pt>
gcc/rust/typecheck/rust-hir-type-check-item.cc
gcc/rust/typecheck/rust-tyty.cc
gcc/testsuite/rust/compile/infer-type-issue-3583.rs [new file with mode: 0644]

index 8c8d7e416147ef54a88a2e7d12c0ca0776bcb9ad..055ce2b2832bd5a4e6d3cbed819ec5be64566bb7 100644 (file)
@@ -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 (),
index 66f5fc5cb2c9b5aae73a25cf0ba70b2185929014..d5ef3b063b4107086a3d9462c660921fc6cb18cf 100644 (file)
@@ -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 (file)
index 0000000..ab4d309
--- /dev/null
@@ -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" }
+}