diff options
author | Philip Herron <herron.philip@googlemail.com> | 2025-04-02 21:02:44 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2025-04-04 08:19:30 +0000 |
commit | 8022ca11ed991cba51843c3226e4de9c2b795ecc (patch) | |
tree | a391150055591aa9dceb54e233bae4b4af6ab6f8 | |
parent | 314090971a51037bb77e36b46c7a10652b9e6c3f (diff) | |
download | gcc-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.cc | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-substitution-mapper.cc | 27 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-substitution-mapper.h | 2 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/issue-3643.rs | 4 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/issue-3646.rs | 7 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/issue-3654.rs | 3 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/issue-3663.rs | 6 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/issue-3671.rs | 2 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/nr2/exclude | 2 |
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> ®ions) { + 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 |