aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust
diff options
context:
space:
mode:
authorPhilip Herron <herron.philip@googlemail.com>2024-10-02 15:47:33 +0100
committerArthur Cohen <arthur.cohen@embecosm.com>2025-03-19 15:32:16 +0100
commit308fd792af6c220b505515e6d40e7ba0f9820cf5 (patch)
tree3eebb2a7582f269c94bdac1353a093639518199e /gcc/rust
parentac5821890051d71cf55169c4f7e91801ca5f8ba2 (diff)
downloadgcc-308fd792af6c220b505515e6d40e7ba0f9820cf5.zip
gcc-308fd792af6c220b505515e6d40e7ba0f9820cf5.tar.gz
gcc-308fd792af6c220b505515e6d40e7ba0f9820cf5.tar.bz2
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.philip@googlemail.com>
Diffstat (limited to 'gcc/rust')
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-resolve.cc27
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-item.cc19
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-item.h3
3 files changed, 33 insertions, 16 deletions
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 51a6417..ec331cf 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 d707e34..3858d51 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 c5b94db..56832e7 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,