diff options
author | Philip Herron <herron.philip@googlemail.com> | 2024-10-02 15:47:33 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2024-10-02 16:42:01 +0000 |
commit | af0f0e3f5384457cecb74608476caf2acd1c5ebc (patch) | |
tree | e1171dd837b4f165832c9294b0760a7ad1d403d9 /gcc | |
parent | ad1c8b1d45ef20e51acef313723bb5b12c58e457 (diff) | |
download | gcc-af0f0e3f5384457cecb74608476caf2acd1c5ebc.zip gcc-af0f0e3f5384457cecb74608476caf2acd1c5ebc.tar.gz gcc-af0f0e3f5384457cecb74608476caf2acd1c5ebc.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')
-rw-r--r-- | gcc/rust/typecheck/rust-hir-trait-resolve.cc | 27 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-item.cc | 19 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-item.h | 3 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/issue-2499.rs | 11 | ||||
-rw-r--r-- | 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 642bf27..9f07f54 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 c1e8107..beb60f3 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 8a90ba0..41252a4 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 0000000..662d58f --- /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 e792462..dec3bdd 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 |