Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions gcc/rust/typecheck/rust-hir-type-check-item.cc
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,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 ())
Expand All @@ -266,6 +267,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 (),
Expand Down
12 changes: 11 additions & 1 deletion gcc/rust/typecheck/rust-tyty.cc
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,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> ())
{
Expand Down Expand Up @@ -778,6 +781,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;
}
Expand Down
23 changes: 23 additions & 0 deletions gcc/testsuite/rust/compile/infer-type-issue-3583.rs
Original file line number Diff line number Diff line change
@@ -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" }

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is [i32; _] detected?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I checked and it ICE's. Should that be fixed in contains_infer? It seems like it should but I'm not sure.

  else if (auto slice = x->try_as<const SliceType> ())
    {
      return slice->get_element_type ()->contains_infer ();
    }

Right now, it only checks for the underlying type, not for the other pattern.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think adding the check to contains_infer makes sense, at least for now :) this case should definitely be

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think adding the check to contains_infer makes sense, at least for now :) this case should definitely be

Thank you, I will be adding this check as soon as possible!

@joao-novo joao-novo Mar 31, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added the check, but I ran into some problems with the ConstInferType's locus not being properly set (which should probably be made into a new issue), so instead of using get_locus, I used the Mappings directly. I also had to add a case for ConstInferType in contains_infer despite there being no other usages of Const... types in the function, because the array capacity is being passed as such. Let me know if there is some other way to do this, or if it's intentional.

}

struct Test14 {
a: [i32; _], // { dg-error "the placeholder ... is not allowed within types on item" }
}
Loading