]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: fix ICE by skipping invalid (non-FNDEF) candidates
authorlishin <lishin1008@gmail.com>
Wed, 13 Aug 2025 18:16:52 +0000 (19:16 +0100)
committerArthur Cohen <arthur.cohen@embecosm.com>
Thu, 30 Oct 2025 19:58:39 +0000 (20:58 +0100)
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 <lishin1008@gmail.com>
gcc/rust/typecheck/rust-hir-dot-operator.cc
gcc/testsuite/rust/compile/issue-3958.rs [new file with mode: 0644]

index f0db7ac81029e47f77ad5732fb7b67b637a5723a..29919aaaec8072380ebd2bdddeadc8d152258de2 100644 (file)
@@ -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 (file)
index 0000000..935b512
--- /dev/null
@@ -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();
+}