Skip to content

Commit

Permalink
gccrs: Fix ICE by adding check for enum candidate's in TypePath resol…
Browse files Browse the repository at this point in the history
…ution

Fixes #2479

gcc/rust/ChangeLog:

	* typecheck/rust-hir-trait-resolve.cc (TraitItemReference::resolve_item):
	always resolve the type even when its an a mandatory trait item
	* typecheck/rust-hir-type-check-type.cc (TypeCheckType::resolve_root_path):
	Add check for enum candidates otherwise you get undefined behaviour

gcc/testsuite/ChangeLog:

	* rust/compile/issue-2479.rs: New test.

Signed-off-by: Philip Herron <[email protected]>
  • Loading branch information
philberty committed Jul 30, 2023
1 parent a3fc40c commit 22f4c74
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 3 deletions.
6 changes: 3 additions & 3 deletions gcc/rust/typecheck/rust-hir-trait-resolve.cc
Original file line number Diff line number Diff line change
Expand Up @@ -339,13 +339,13 @@ TraitItemReference::resolve_item (HIR::TraitItemConst &constant)
void
TraitItemReference::resolve_item (HIR::TraitItemFunc &func)
{
if (!is_optional ())
return;

TyTy::BaseType *item_tyty = get_tyty ();
if (item_tyty->get_kind () == TyTy::TypeKind::ERROR)
return;

if (!is_optional ())
return;

// check the block and return types
rust_assert (item_tyty->get_kind () == TyTy::TypeKind::FNDEF);

Expand Down
18 changes: 18 additions & 0 deletions gcc/rust/typecheck/rust-hir-type-check-type.cc
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,16 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset,
*root_resolved_node_id = ref_node_id;
*offset = *offset + 1;
root_tyty = lookup;

// this enforces the proper get_segments checks to take place
bool is_adt = root_tyty->get_kind () == TyTy::TypeKind::ADT;
if (is_adt)
{
const TyTy::ADTType &adt
= *static_cast<const TyTy::ADTType *> (root_tyty);
if (adt.is_enum ())
return root_tyty;
}
}

return root_tyty;
Expand Down Expand Up @@ -498,6 +508,14 @@ TypeCheckType::resolve_segments (
prev_segment = tyseg;
tyseg = candidate.ty;

if (candidate.is_enum_candidate ())
{
rust_error_at (seg->get_locus (),
"expected type, found variant of %s",
tyseg->get_name ().c_str ());
return new TyTy::ErrorType (expr_id);
}

if (candidate.is_impl_candidate ())
{
resolved_node_id
Expand Down
22 changes: 22 additions & 0 deletions gcc/testsuite/rust/compile/issue-2479.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#![allow(unused)]
fn main() {
enum Dragon {
Born,
}

fn oblivion() -> Dragon::Born {
// { dg-error "expected type, found variant of Dragon" "" { target *-*-* } .-1 }
// { dg-error "failed to resolve return type" "" { target *-*-* } .-2 }
Dragon::Born
}

enum Wizard {
Gandalf,
Saruman,
}

trait Isengard {
fn wizard(_: Wizard::Saruman);
// { dg-error "expected type, found variant of Wizard" "" { target *-*-* } .-1 }
}
}

0 comments on commit 22f4c74

Please sign in to comment.