From 11bec2ca6029cb607585f150c2ba9b2ade743dc8 Mon Sep 17 00:00:00 2001 From: lishin Date: Wed, 13 Aug 2025 19:16:52 +0100 Subject: [PATCH] gccrs: fix ICE by skipping invalid (non-FNDEF) candidates gcc/rust/ChangeLog: * typecheck/rust-hir-dot-operator.cc (MethodResolver::Select): Skip asserts by checking candidate type and using early-continue. (MethodResolver::try_select_predicate_candidates): Skip invalid candidates. gcc/testsuite/ChangeLog: * rust/compile/issue-3958.rs: New test. Signed-off-by: lishin --- gcc/rust/typecheck/rust-hir-dot-operator.cc | 26 ++++++++++++++------- gcc/testsuite/rust/compile/issue-3958.rs | 11 +++++++++ 2 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/rust/compile/issue-3958.rs diff --git a/gcc/rust/typecheck/rust-hir-dot-operator.cc b/gcc/rust/typecheck/rust-hir-dot-operator.cc index f0db7ac81029..29919aaaec80 100644 --- a/gcc/rust/typecheck/rust-hir-dot-operator.cc +++ b/gcc/rust/typecheck/rust-hir-dot-operator.cc @@ -51,6 +51,9 @@ MethodResolver::Select (std::set &candidates, { TyTy::BaseType *candidate_type = candidate.candidate.ty; rust_assert (candidate_type->get_kind () == TyTy::TypeKind::FNDEF); + if (candidate_type == nullptr + || candidate_type->get_kind () != TyTy::TypeKind::FNDEF) + continue; TyTy::FnType &fn = *static_cast (candidate_type); // match the number of arguments @@ -136,11 +139,11 @@ MethodResolver::assemble_inherent_impl_candidates ( TyTy::BaseType *ty = nullptr; if (!query_type (func->get_mappings ().get_hirid (), &ty)) return true; - rust_assert (ty != nullptr); - if (ty->get_kind () == TyTy::TypeKind::ERROR) + if (ty == nullptr || ty->get_kind () == TyTy::TypeKind::ERROR) + return true; + if (ty->get_kind () != TyTy::TypeKind::FNDEF) return true; - rust_assert (ty->get_kind () == TyTy::TypeKind::FNDEF); TyTy::FnType *fnty = static_cast (ty); const TyTy::BaseType *impl_self = TypeCheckItem::ResolveImplBlockSelf (*impl); @@ -220,10 +223,11 @@ MethodResolver::assemble_trait_impl_candidates ( TyTy::BaseType *ty = nullptr; if (!query_type (func->get_mappings ().get_hirid (), &ty)) continue; - if (ty->get_kind () == TyTy::TypeKind::ERROR) + if (ty == nullptr || ty->get_kind () == TyTy::TypeKind::ERROR) + continue; + if (ty->get_kind () != TyTy::TypeKind::FNDEF) continue; - rust_assert (ty->get_kind () == TyTy::TypeKind::FNDEF); TyTy::FnType *fnty = static_cast (ty); const TyTy::BaseType *impl_self = TypeCheckItem::ResolveImplBlockSelf (*impl); @@ -282,7 +286,8 @@ MethodResolver::assemble_trait_impl_candidates ( return true; TyTy::BaseType *ty = item_ref->get_tyty (); - rust_assert (ty->get_kind () == TyTy::TypeKind::FNDEF); + if (ty == nullptr || ty->get_kind () != TyTy::TypeKind::FNDEF) + return true; TyTy::FnType *fnty = static_cast (ty); trait_candidates.emplace_back (func, trait, fnty, trait_ref, item_ref); @@ -298,7 +303,8 @@ MethodResolver::try_select_predicate_candidates (TyTy::BaseType &receiver) for (const auto &predicate : predicate_items) { const TyTy::FnType *fn = predicate.fntype; - rust_assert (fn->is_method ()); + if (!fn->is_method ()) + continue; TyTy::BaseType *fn_self = fn->get_self_type (); rust_debug ("dot-operator predicate fn_self={%s} can_eq receiver={%s}", @@ -345,7 +351,8 @@ MethodResolver::try_select_inherent_impl_candidates ( continue; TyTy::FnType *fn = impl_item.ty; - rust_assert (fn->is_method ()); + if (!fn->is_method ()) + continue; TyTy::BaseType *fn_self = fn->get_self_type (); @@ -383,7 +390,8 @@ MethodResolver::try_select_trait_impl_candidates ( for (auto trait_item : candidates) { TyTy::FnType *fn = trait_item.ty; - rust_assert (fn->is_method ()); + if (!fn->is_method ()) + continue; TyTy::BaseType *fn_self = fn->get_self_type (); rust_debug ("dot-operator trait_item fn_self={%s} can_eq receiver={%s}", diff --git a/gcc/testsuite/rust/compile/issue-3958.rs b/gcc/testsuite/rust/compile/issue-3958.rs new file mode 100644 index 000000000000..935b512c79dd --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3958.rs @@ -0,0 +1,11 @@ +// { dg-options "-fsyntax-only" } +trait A { + fn a(&self) -> ::X; +} + +impl A for u32 {} + +fn main() { + let a: u32 = 0; + let b: u32 = a.a(); +}