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 +}
