[COMMITTED 68/83] gccrs: filter out candidates by checking if self is compatable

arthur.cohen@opensrcsec.com arthur.cohen@opensrcsec.com
Wed Sep 16 12:30:27 GMT 2026


From: Philip Herron <herron.philip@googlemail.com>

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 <herron.philip@googlemail.com>
---
 .../typecheck/rust-hir-type-check-expr.cc     |  6 ++++
 .../rust/execute/torture/issue-4866.rs        | 33 +++++++++++++++++++
 2 files changed, 39 insertions(+)
 create mode 100644 gcc/testsuite/rust/execute/torture/issue-4866.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index a1e4fb5d8f6..c4cca34ca69 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 00000000000..2935febd6da
--- /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
+}
-- 
2.50.1



More information about the Gcc-rust mailing list