Skip to content

Commit

Permalink
gccrs: Fix ICE when typechecking non-trait item when we expect one
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
philberty committed Oct 2, 2024
1 parent ad1c8b1 commit af0f0e3
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 17 deletions.
27 changes: 17 additions & 10 deletions gcc/rust/typecheck/rust-hir-trait-resolve.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 *
Expand Down
19 changes: 14 additions & 5 deletions gcc/rust/typecheck/rust-hir-type-check-item.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 *
Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion gcc/rust/typecheck/rust-hir-type-check-item.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ class TypeCheckItem : private TypeCheckBase, private HIR::HIRVisItemVisitor
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,
Expand Down
11 changes: 11 additions & 0 deletions gcc/testsuite/rust/compile/issue-2499.rs
Original file line number Diff line number Diff line change
@@ -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 }
3 changes: 2 additions & 1 deletion gcc/testsuite/rust/compile/nr2/exclude
Original file line number Diff line number Diff line change
Expand Up @@ -254,4 +254,5 @@ issue-3139-2.rs
issue-3139-3.rs
issue-3036.rs
issue-2951.rs
issue-2203.rs
issue-2203.rs
issue-2499.rs

0 comments on commit af0f0e3

Please sign in to comment.