aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <herron.philip@googlemail.com>2025-04-02 21:02:44 +0100
committerPhilip Herron <philip.herron@embecosm.com>2025-04-04 08:19:30 +0000
commit8022ca11ed991cba51843c3226e4de9c2b795ecc (patch)
treea391150055591aa9dceb54e233bae4b4af6ab6f8
parent314090971a51037bb77e36b46c7a10652b9e6c3f (diff)
downloadgcc-8022ca11ed991cba51843c3226e4de9c2b795ecc.zip
gcc-8022ca11ed991cba51843c3226e4de9c2b795ecc.tar.gz
gcc-8022ca11ed991cba51843c3226e4de9c2b795ecc.tar.bz2
gccrs: Fix ICE when hitting invalid types for generics
We need to check upfront if the type is valid or not. Then error with a decent message. Fixes Rust-GCC#3643 Fixes Rust-GCC#3646 Fixes Rust-GCC#3654 Fixes Rust-GCC#3663 Fixes Rust-GCC#3671 gcc/rust/ChangeLog: * resolve/rust-ast-resolve-type.cc (ResolveRelativeTypePath::go): fix error msg * typecheck/rust-substitution-mapper.cc (SubstMapper::Resolve): add validation (SubstMapper::valid_type): new check (SubstMapper::visit): check if can resolve * typecheck/rust-substitution-mapper.h: new prototype gcc/testsuite/ChangeLog: * rust/compile/nr2/exclude: nr2 is missing type path error * rust/compile/issue-3643.rs: New test. * rust/compile/issue-3646.rs: New test. * rust/compile/issue-3654.rs: New test. * rust/compile/issue-3663.rs: New test. * rust/compile/issue-3671.rs: New test. Signed-off-by: Philip Herron <herron.philip@googlemail.com>
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.cc2
-rw-r--r--gcc/rust/typecheck/rust-substitution-mapper.cc27
-rw-r--r--gcc/rust/typecheck/rust-substitution-mapper.h2
-rw-r--r--gcc/testsuite/rust/compile/issue-3643.rs4
-rw-r--r--gcc/testsuite/rust/compile/issue-3646.rs7
-rw-r--r--gcc/testsuite/rust/compile/issue-3654.rs3
-rw-r--r--gcc/testsuite/rust/compile/issue-3663.rs6
-rw-r--r--gcc/testsuite/rust/compile/issue-3671.rs2
-rw-r--r--gcc/testsuite/rust/compile/nr2/exclude2
9 files changed, 53 insertions, 2 deletions
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc b/gcc/rust/resolve/rust-ast-resolve-type.cc
index c1c4022..135504e 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-type.cc
@@ -357,7 +357,7 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id)
{
rust_error_at (segment->get_locus (), ErrorCode::E0412,
"could not resolve type path %qs",
- segment->as_string ().c_str ());
+ segment->get_ident_segment ().as_string ().c_str ());
return false;
}
}
diff --git a/gcc/rust/typecheck/rust-substitution-mapper.cc b/gcc/rust/typecheck/rust-substitution-mapper.cc
index 20fe8f0..878c4d5 100644
--- a/gcc/rust/typecheck/rust-substitution-mapper.cc
+++ b/gcc/rust/typecheck/rust-substitution-mapper.cc
@@ -34,6 +34,15 @@ SubstMapper::Resolve (TyTy::BaseType *base, location_t locus,
HIR::GenericArgs *generics,
const std::vector<TyTy::Region> &regions)
{
+ if (!valid_type (base))
+ {
+ rich_location r (line_table, locus);
+ r.add_fixit_remove (generics->get_locus ());
+ rust_error_at (r, ErrorCode::E0109,
+ "generic arguments are not allowed for this type");
+ return base;
+ }
+
SubstMapper mapper (base->get_ref (), generics, regions, locus);
base->accept_vis (mapper);
rust_assert (mapper.resolved != nullptr);
@@ -47,6 +56,17 @@ SubstMapper::InferSubst (TyTy::BaseType *base, location_t locus)
}
bool
+SubstMapper::valid_type (TyTy::BaseType *base)
+{
+ bool is_fn = base->is<TyTy::FnType> ();
+ bool is_adt = base->is<TyTy::ADTType> ();
+ bool is_placeholder = base->is<TyTy::PlaceholderType> ();
+ bool is_projection = base->is<TyTy::ProjectionType> ();
+
+ return is_fn || is_adt || is_placeholder || is_projection;
+}
+
+bool
SubstMapper::have_generic_args () const
{
return generics != nullptr;
@@ -103,7 +123,12 @@ SubstMapper::visit (TyTy::ADTType &type)
void
SubstMapper::visit (TyTy::PlaceholderType &type)
{
- rust_assert (type.can_resolve ());
+ if (!type.can_resolve ())
+ {
+ resolved = &type;
+ return;
+ }
+
resolved = SubstMapper::Resolve (type.resolve (), locus, generics, regions);
}
diff --git a/gcc/rust/typecheck/rust-substitution-mapper.h b/gcc/rust/typecheck/rust-substitution-mapper.h
index a0aba56..2f03e4b 100644
--- a/gcc/rust/typecheck/rust-substitution-mapper.h
+++ b/gcc/rust/typecheck/rust-substitution-mapper.h
@@ -37,6 +37,8 @@ public:
bool have_generic_args () const;
+ static bool valid_type (TyTy::BaseType *base);
+
void visit (TyTy::FnType &type) override;
void visit (TyTy::ADTType &type) override;
void visit (TyTy::PlaceholderType &type) override;
diff --git a/gcc/testsuite/rust/compile/issue-3643.rs b/gcc/testsuite/rust/compile/issue-3643.rs
new file mode 100644
index 0000000..bed9ffc
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3643.rs
@@ -0,0 +1,4 @@
+fn foo() {
+ let x: usize<foo>;
+ // { dg-error "generic arguments are not allowed for this type .E0109." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3646.rs b/gcc/testsuite/rust/compile/issue-3646.rs
new file mode 100644
index 0000000..80693cb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3646.rs
@@ -0,0 +1,7 @@
+trait Foo {
+ type T;
+ fn foo() -> Foo<main>;
+ // { dg-error "generic arguments are not allowed for this type .E0109." "" { target *-*-* } .-1 }
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-3654.rs b/gcc/testsuite/rust/compile/issue-3654.rs
new file mode 100644
index 0000000..923488e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3654.rs
@@ -0,0 +1,3 @@
+type Meeshka = Mow<!>;
+// { dg-error "generic arguments are not allowed for this type .E0109." "" { target *-*-* } .-1 }
+type Mow = &'static fn(!) -> !;
diff --git a/gcc/testsuite/rust/compile/issue-3663.rs b/gcc/testsuite/rust/compile/issue-3663.rs
new file mode 100644
index 0000000..0f0559c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3663.rs
@@ -0,0 +1,6 @@
+pub trait TypeFn {}
+
+impl TypeFn for Output<{ 42 }> {
+ // { dg-error "could not resolve type path .Output. .E0412." "" { target *-*-* } .-1 }
+ type Output = ();
+}
diff --git a/gcc/testsuite/rust/compile/issue-3671.rs b/gcc/testsuite/rust/compile/issue-3671.rs
new file mode 100644
index 0000000..e800d53
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3671.rs
@@ -0,0 +1,2 @@
+impl Self<0> {}
+// { dg-error "could not resolve type path" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/nr2/exclude b/gcc/testsuite/rust/compile/nr2/exclude
index ca72571..adc199e 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -28,4 +28,6 @@ torture/loop4.rs
torture/loop8.rs
torture/name_resolve1.rs
issue-3568.rs
+issue-3663.rs
+issue-3671.rs
# please don't delete the trailing newline