From 432cdee6a6e28c52dae6b69079db301b9681485b Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Sun, 30 Jul 2023 18:59:06 +0100 Subject: [PATCH] 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 --- gcc/rust/typecheck/rust-hir-trait-resolve.cc | 6 ++--- .../typecheck/rust-hir-type-check-type.cc | 18 +++++++++++++++ gcc/testsuite/rust/compile/issue-2479.rs | 22 +++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/rust/compile/issue-2479.rs diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc index 17827753198c..b99fe2341af5 100644 --- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc +++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc @@ -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); diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc index 03ee74aeb105..b3125f7e1a5e 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc @@ -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 (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 diff --git a/gcc/testsuite/rust/compile/issue-2479.rs b/gcc/testsuite/rust/compile/issue-2479.rs new file mode 100644 index 000000000000..4a0d3547b750 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2479.rs @@ -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 } +} +} -- 2.47.2