https://gcc.gnu.org/g:308fd792af6c220b505515e6d40e7ba0f9820cf5

commit r15-8422-g308fd792af6c220b505515e6d40e7ba0f9820cf5
Author: Philip Herron <herron.phi...@googlemail.com>
Date:   Wed Oct 2 15:47:33 2024 +0100

    gccrs: Fix ICE when typechecking non-trait item when we expect one
    
    We just had an assertion here for this case where we expect a trait.
    This changes the assertion into error handling producing the correct
    error code with fixit suggestion like rustc.
    
    Fixes #2499
    
    gcc/rust/ChangeLog:
    
            * typecheck/rust-hir-trait-resolve.cc 
(TraitResolver::resolve_path_to_trait):
            use error handling instead of assertion
            * typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): 
reuse trait reference
            * typecheck/rust-hir-type-check-item.h: update prototype
    
    gcc/testsuite/ChangeLog:
    
            * rust/compile/nr2/exclude: nr2 cant handle this
            * rust/compile/issue-2499.rs: New test.
    
    Signed-off-by: Philip Herron <herron.phi...@googlemail.com>

Diff:
---
 gcc/rust/typecheck/rust-hir-trait-resolve.cc   | 27 ++++++++++++++++----------
 gcc/rust/typecheck/rust-hir-type-check-item.cc | 19 +++++++++++++-----
 gcc/rust/typecheck/rust-hir-type-check-item.h  |  3 ++-
 gcc/testsuite/rust/compile/issue-2499.rs       | 11 +++++++++++
 gcc/testsuite/rust/compile/nr2/exclude         |  3 ++-
 5 files changed, 46 insertions(+), 17 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc 
b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 51a64174ea4d..ec331cf6e95c 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -117,19 +117,26 @@ TraitResolver::resolve_path_to_trait (const HIR::TypePath 
&path,
       return false;
     }
 
-  if (auto hid = mappings.lookup_node_to_hir (ref))
+  auto hid = mappings.lookup_node_to_hir (ref);
+  if (!hid)
     {
-      tl::optional<HIR::Item *> resolved_item
-       = mappings.lookup_hir_item (hid.value ());
-      rust_assert (resolved_item.has_value ());
-      rust_assert (resolved_item.value ()->get_item_kind ()
-                  == HIR::Item::ItemKind::Trait);
-      *resolved = static_cast<HIR::Trait *> (*resolved_item);
+      rust_error_at (path.get_locus (), "Failed to resolve path to hir-id");
+      return false;
+    }
 
-      return true;
+  auto resolved_item = mappings.lookup_hir_item (hid.value ());
+  rust_assert (resolved_item.has_value ());
+  if (resolved_item.value ()->get_item_kind () != HIR::Item::ItemKind::Trait)
+    {
+      rich_location r (line_table, path.get_locus ());
+      r.add_fixit_replace ("not a trait");
+      rust_error_at (r, ErrorCode::E0404, "Expected a trait found %qs",
+                    path.as_simple_path ().as_string ().c_str ());
+      return false;
     }
-  rust_error_at (path.get_locus (), "Failed to resolve path to hir-id");
-  return false;
+
+  *resolved = static_cast<HIR::Trait *> (*resolved_item);
+  return true;
 }
 
 TraitReference *
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc 
b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index d707e3458f1d..3858d5132f9a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -453,6 +453,15 @@ TypeCheckItem::visit (HIR::ImplBlock &impl_block)
 {
   auto binder_pin = context->push_clean_lifetime_resolver (true);
 
+  TraitReference *trait_reference = &TraitReference::error_node ();
+  if (impl_block.has_trait_ref ())
+    {
+      std::unique_ptr<HIR::TypePath> &ref = impl_block.get_trait_ref ();
+      trait_reference = TraitResolver::Resolve (*ref);
+      if (trait_reference->is_error ())
+       return;
+    }
+
   bool failed_flag = false;
   auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
   if (failed_flag)
@@ -474,7 +483,7 @@ TypeCheckItem::visit (HIR::ImplBlock &impl_block)
     }
 
   // validate the impl items
-  validate_trait_impl_block (impl_block, self, substitutions);
+  validate_trait_impl_block (trait_reference, impl_block, self, substitutions);
 }
 
 TyTy::BaseType *
@@ -698,16 +707,16 @@ TypeCheckItem::resolve_impl_block_substitutions 
(HIR::ImplBlock &impl_block,
 
 void
 TypeCheckItem::validate_trait_impl_block (
-  HIR::ImplBlock &impl_block, TyTy::BaseType *self,
+  TraitReference *trait_reference, HIR::ImplBlock &impl_block,
+  TyTy::BaseType *self,
   std::vector<TyTy::SubstitutionParamMapping> &substitutions)
 {
   auto specified_bound = TyTy::TypeBoundPredicate::error ();
-  TraitReference *trait_reference = &TraitReference::error_node ();
   if (impl_block.has_trait_ref ())
     {
       std::unique_ptr<HIR::TypePath> &ref = impl_block.get_trait_ref ();
-      trait_reference = TraitResolver::Resolve (*ref);
-      rust_assert (!trait_reference->is_error ());
+      if (trait_reference->is_error ())
+       return;
 
       // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
       // for example
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h 
b/gcc/rust/typecheck/rust-hir-type-check-item.h
index c5b94db2cb5d..56832e75ccdb 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.h
@@ -63,7 +63,8 @@ protected:
                                    bool &failure_flag);
 
   void validate_trait_impl_block (
-    HIR::ImplBlock &impl_block, TyTy::BaseType *self,
+    TraitReference *trait_reference, HIR::ImplBlock &impl_block,
+    TyTy::BaseType *self,
     std::vector<TyTy::SubstitutionParamMapping> &substitutions);
 
   TyTy::BaseType *resolve_impl_item (HIR::ImplBlock &impl_block,
diff --git a/gcc/testsuite/rust/compile/issue-2499.rs 
b/gcc/testsuite/rust/compile/issue-2499.rs
new file mode 100644
index 000000000000..662d58fb5b12
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2499.rs
@@ -0,0 +1,11 @@
+#[lang = "sized"]
+pub trait Sized {}
+
+struct Foo;
+struct Bar;
+
+impl Foo for Bar {}
+// { dg-error "Expected a trait found .Foo. .E0404." "" { target *-*-* } .-1 }
+
+fn baz<T: Foo>(t: T) {}
+// { dg-error "Expected a trait found .Foo. .E0404." "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index e792462ba332..dec3bdd4d18e 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -254,4 +254,5 @@ issue-3139-2.rs
 issue-3139-3.rs
 issue-3036.rs
 issue-2951.rs
-issue-2203.rs
\ No newline at end of file
+issue-2203.rs
+issue-2499.rs
\ No newline at end of file

Reply via email to