https://gcc.gnu.org/g:18ad6345e6df72ca010952d972dfadef3195a64b
commit r17-4352-g18ad6345e6df72ca010952d972dfadef3195a64b Author: Philip Herron <[email protected]> Date: Thu Sep 10 21:02:28 2026 +0100 gccrs: Fix bad derive of Ord to use Self instead of raw type-name The raw type name doesnt capture the generic state of the impl but Self does. Fixes Rust-GCC/gccrs#4879 gcc/rust/ChangeLog: * expand/rust-derive-ord.cc (DeriveOrd::cmp_fn): use Self gcc/testsuite/ChangeLog: * rust/compile/issue-4879.rs: New test. Signed-off-by: Philip Herron <[email protected]> Diff: --- gcc/rust/expand/rust-derive-ord.cc | 13 ++++--- gcc/testsuite/rust/compile/issue-4879.rs | 65 ++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/gcc/rust/expand/rust-derive-ord.cc b/gcc/rust/expand/rust-derive-ord.cc index aae7f8414814..7960d2978dab 100644 --- a/gcc/rust/expand/rust-derive-ord.cc +++ b/gcc/rust/expand/rust-derive-ord.cc @@ -100,11 +100,14 @@ DeriveOrd::cmp_fn (std::unique_ptr<BlockExpr> &&block, Identifier type_name) } // &self, other: &Self - auto params = vec ( - builder.self_ref_param (), - builder.function_param (builder.identifier_pattern ("other"), - builder.reference_type (ptrify ( - builder.type_path (type_name.as_string ()))))); + // + // this must be Self for a generic type Wrapping<T> the bare struct name has + // no type arguments + auto params + = vec (builder.self_ref_param (), + builder.function_param (builder.identifier_pattern ("other"), + builder.reference_type ( + ptrify (builder.type_path ("Self"))))); auto function_name = fn (ordering); diff --git a/gcc/testsuite/rust/compile/issue-4879.rs b/gcc/testsuite/rust/compile/issue-4879.rs new file mode 100644 index 000000000000..e2e8ac1078bc --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-4879.rs @@ -0,0 +1,65 @@ +#![feature(no_core, lang_items)] +#![no_core] + +#[lang = "sized"] +pub trait Sized {} + +#[lang = "structural_peq"] +pub trait StructuralPartialEq {} + +#[lang = "structural_teq"] +pub trait StructuralEq {} + +#[lang = "phantom_data"] +pub struct PhantomData<T: ?Sized>; + +pub mod option { + pub enum Option<T> { + #[lang = "None"] + None, + #[lang = "Some"] + Some(T), + } +} + +pub use option::Option; + +pub mod cmp { + use crate::Sized; + + #[lang = "eq"] + pub trait PartialEq<Rhs: ?Sized = Self> { + fn eq(&self, other: &Rhs) -> bool; + fn ne(&self, other: &Rhs) -> bool { + !self.eq(other) + } + } + + pub trait Eq: PartialEq<Self> { + fn assert_receiver_is_total_eq(&self) {} + } + + pub enum Ordering { + Less = -1, + Equal = 0, + Greater = 1, + } + + #[lang = "partial_ord"] + pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> { + fn partial_cmp(&self, other: &Rhs) -> crate::Option<Ordering>; + } + + pub trait Ord: Eq + PartialOrd<Self> { + fn cmp(&self, other: &Self) -> Ordering; + } +} + +use cmp::{Eq, Ord, PartialEq, PartialOrd}; + +#[derive(PartialEq, PartialOrd, Eq, Ord)] +pub struct Wrapping<T>(pub T); + +fn main() -> i32 { + 0 +}
