From: João Novo <[email protected]>

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]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: 
https://github.com/Rust-GCC/gccrs/commit/407b7e6c52619bb81e201293a52819bbe22d9c8e

The commit has NOT been mentioned in any issue.

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4504

 .../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(-)
 create mode 100644 gcc/testsuite/rust/compile/infer-type-issue-3583.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc 
b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index 8c8d7e416..055ce2b28 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 66f5fc5cb..d5ef3b063 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 000000000..ab4d30967
--- /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" }
+}

base-commit: 06e19241a8a023f58a0ca9dcd3b9f3d3dea0f0bf
-- 
2.54.0

Reply via email to