https://gcc.gnu.org/g:233155410f6e1c35b1cbc54be1ebc1a099777e91
commit r16-4789-g233155410f6e1c35b1cbc54be1ebc1a099777e91 Author: lishin <[email protected]> Date: Wed Aug 13 19:16:52 2025 +0100 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 <[email protected]> Diff: --- gcc/rust/typecheck/rust-hir-dot-operator.cc | 26 +++++++++++++++++--------- gcc/testsuite/rust/compile/issue-3958.rs | 11 +++++++++++ 2 files changed, 28 insertions(+), 9 deletions(-) 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<MethodCandidate> &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<TyTy::FnType *> (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<TyTy::FnType *> (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<TyTy::FnType *> (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<TyTy::FnType *> (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) -> <Self as A>::X; +} + +impl A for u32 {} + +fn main() { + let a: u32 = 0; + let b: u32 = a.a(); +}
