https://gcc.gnu.org/g:8022ca11ed991cba51843c3226e4de9c2b795ecc

commit 8022ca11ed991cba51843c3226e4de9c2b795ecc
Author: Philip Herron <herron.phi...@googlemail.com>
Date:   Wed Apr 2 21:02:44 2025 +0100

    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.phi...@googlemail.com>

Diff:
---
 gcc/rust/resolve/rust-ast-resolve-type.cc      |  2 +-
 gcc/rust/typecheck/rust-substitution-mapper.cc | 27 +++++++++++++++++++++++++-
 gcc/rust/typecheck/rust-substitution-mapper.h  |  2 ++
 gcc/testsuite/rust/compile/issue-3643.rs       |  4 ++++
 gcc/testsuite/rust/compile/issue-3646.rs       |  7 +++++++
 gcc/testsuite/rust/compile/issue-3654.rs       |  3 +++
 gcc/testsuite/rust/compile/issue-3663.rs       |  6 ++++++
 gcc/testsuite/rust/compile/issue-3671.rs       |  2 ++
 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 c1c40227b4f3..135504ed9b5e 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 20fe8f04adcb..878c4d54a0a8 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);
@@ -46,6 +55,17 @@ SubstMapper::InferSubst (TyTy::BaseType *base, location_t 
locus)
   return SubstMapper::Resolve (base, locus, nullptr, {});
 }
 
+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
 {
@@ -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 a0aba567d24e..2f03e4b7b359 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 000000000000..bed9ffc0c2b9
--- /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 000000000000..80693cb9bdb2
--- /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 000000000000..923488e28efc
--- /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 000000000000..0f0559c93393
--- /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 000000000000..e800d536e02c
--- /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 ca7257191960..adc199e59e38 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

Reply via email to