gccrs: Fix ICE by adding check for enum candidate's in TypePath resolution

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 <herron.philip@googlemail.com>
This commit is contained in:
Philip Herron 2023-07-30 18:59:06 +01:00 committed by Arthur Cohen
parent f7b2e17682
commit 432cdee6a6
3 changed files with 43 additions and 3 deletions

View file

@ -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);

View file

@ -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;
@ -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

View file

@ -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 }
}
}