https://gcc.gnu.org/g:491fddc08dddf2d1ab28ff17799ad83dd280ffc0

commit r17-4345-g491fddc08dddf2d1ab28ff17799ad83dd280ffc0
Author: Philip Herron <[email protected]>
Date:   Tue Sep 8 11:57:15 2026 +0100

    gccrs: filter out candidates by checking if self is compatable
    
    We have PartialOrd for &i8 and a reference &&A so we need to filter out the
    double reference one early on.
    
    Fixes Rust-GCC/gccrs#4866
    
    gcc/rust/ChangeLog:
    
            * typecheck/rust-hir-type-check-expr.cc: check candidate self
    
    gcc/testsuite/ChangeLog:
    
            * rust/execute/torture/issue-4866.rs: New test.
    
    Signed-off-by: Philip Herron <[email protected]>

Diff:
---
 gcc/rust/typecheck/rust-hir-type-check-expr.cc   |  6 +++++
 gcc/testsuite/rust/execute/torture/issue-4866.rs | 33 ++++++++++++++++++++++++
 2 files changed, 39 insertions(+)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index a1e4fb5d8f63..c4cca34ca697 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -2070,6 +2070,12 @@ TypeCheckExpr::resolve_operator_overload (
       const TyTy::FnType &fn
        = *static_cast<const TyTy::FnType *> (candidate_type);
 
+      if (probe_lhs != nullptr
+         && !types_compatable (TyTy::TyWithLocation (fn.get_self_type ()),
+                               TyTy::TyWithLocation (probe_lhs),
+                               UNDEF_LOCATION, false /* emit_errors */))
+       continue;
+
       DefId current_fn_defid = current_context.get_defid ();
       bool recursive_candidated = fn.get_id () == current_fn_defid;
       if (!recursive_candidated)
diff --git a/gcc/testsuite/rust/execute/torture/issue-4866.rs 
b/gcc/testsuite/rust/execute/torture/issue-4866.rs
new file mode 100644
index 000000000000..2935febd6da7
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-4866.rs
@@ -0,0 +1,33 @@
+#![feature(no_core, lang_items)]
+#![no_core]
+#[lang = "sized"]
+pub trait Sized {}
+#[lang = "partial_ord"]
+trait PartialOrd<Rhs: ?Sized = Self> {
+    fn lt(&self, rhs: &Rhs) -> bool;
+}
+impl PartialOrd for i8 {
+    fn lt(&self, other: &i8) -> bool {
+        *self < *other
+    }
+}
+impl<A: ?Sized, B: ?Sized> PartialOrd<&B> for &A
+where
+    A: PartialOrd<B>,
+{
+    fn lt(&self, other: &&B) -> bool {
+        PartialOrd::lt(*self, *other)
+    }
+}
+
+fn main() -> i32 {
+    let a = 1i8;
+    let b = 2i8;
+    if !(a < b) || b < a {
+        return 1;
+    }
+    if !(&a < &b) || &b < &a {
+        return 2;
+    }
+    0
+}

Reply via email to