From: lishin <[email protected]>

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]>
---
 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 f0db7ac8102..29919aaaec8 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 00000000000..935b512c79d
--- /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();
+}
-- 
2.50.1

Reply via email to