Skip to content

Commit d7e2310

Browse files
committed
gccrs: Fix issues around PartialEq Eq Ord Partial Ord
There is still an issue with derive on PartialOrd but this adds good tests and fixes a bug we had handling the default Rhs = Self generic type param substitutions on the comparison traits. gcc/rust/ChangeLog: * typecheck/rust-tyty.cc (ParamType::handle_substitions): make this consistent gcc/testsuite/ChangeLog: * rust/compile/bug-with-default-generic.rs: New test. * rust/execute/torture/partial-eq-1.rs: New test. * rust/execute/torture/partial-eq-2.rs: New test. * rust/execute/torture/partial-eq-3.rs: New test. * rust/execute/torture/partial-eq-4.rs: New test. * rust/execute/torture/partial-ord-1.rs: New test. * rust/execute/torture/partial-ord-2.rs: New test. * rust/execute/torture/partial-ord-3.rs: New test. * rust/execute/torture/partial-ord-4.rs: New test. * rust/execute/torture/partial-ord-5.rs: New test. Signed-off-by: Philip Herron <[email protected]>
1 parent d31e537 commit d7e2310

File tree

11 files changed

+2758
-5
lines changed

11 files changed

+2758
-5
lines changed

gcc/rust/typecheck/rust-tyty.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3545,12 +3545,12 @@ ParamType::handle_substitions (SubstitutionArgumentMappings &subst_mappings)
35453545
ParamType *p = static_cast<ParamType *> (clone ());
35463546
subst_mappings.on_param_subst (*p, arg);
35473547

3548-
// there are two cases one where we substitute directly to a new PARAM and
3549-
// otherwise
3550-
if (arg.get_tyty ()->get_kind () == TyTy::TypeKind::PARAM)
3548+
const BaseType *resolved = arg.get_tyty ();
3549+
if (resolved->get_kind () == TyTy::TypeKind::PARAM)
35513550
{
3552-
p->set_ty_ref (arg.get_tyty ()->get_ref ());
3553-
return p;
3551+
const ParamType &pp = *static_cast<const ParamType *> (resolved);
3552+
if (pp.can_resolve ())
3553+
resolved = pp.resolve ();
35543554
}
35553555

35563556
// this is the new subst that this needs to pass
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#[lang = "sized"]
2+
pub trait Sized {}
3+
4+
pub trait MyBinaryTrait<Rhs = Self> {
5+
fn do_something(&self, rhs: &Rhs);
6+
}
7+
8+
struct Foo<T> {
9+
// { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
10+
value: T,
11+
}
12+
13+
impl<T> MyBinaryTrait for Foo<T> {
14+
fn do_something(&self, _rhs: &Self) {}
15+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/* { dg-output "a == b\r*\na != c\r*\n" }*/
2+
/* { dg-options "-w" } */
3+
4+
mod core {
5+
mod marker {
6+
#[lang = "phantom_data"]
7+
#[stable(feature = "rust1", since = "1.0.0")]
8+
pub struct PhantomData<T: ?Sized>;
9+
10+
#[unstable(feature = "structural_match", issue = "31434")]
11+
#[lang = "structural_peq"]
12+
pub trait StructuralPartialEq {
13+
// Empty.
14+
}
15+
16+
#[unstable(feature = "structural_match", issue = "31434")]
17+
#[lang = "structural_teq"]
18+
pub trait StructuralEq {
19+
// Empty.
20+
}
21+
22+
#[lang = "sized"]
23+
pub trait Sized {}
24+
}
25+
26+
pub mod cmp {
27+
use super::marker::Sized;
28+
29+
#[lang = "eq"]
30+
pub trait PartialEq<Rhs: ?Sized = Self> {
31+
fn eq(&self, other: &Rhs) -> bool;
32+
33+
fn ne(&self, other: &Rhs) -> bool {
34+
!self.eq(other)
35+
}
36+
}
37+
38+
pub trait Eq: PartialEq<Self> {
39+
fn assert_receiver_is_total_eq(&self) {}
40+
}
41+
}
42+
}
43+
44+
use core::cmp::{Eq, PartialEq};
45+
46+
// PartialEq for i32 and u32 so we can compare across types
47+
impl PartialEq<u32> for i32 {
48+
fn eq(&self, other: &u32) -> bool {
49+
*self >= 0 && (*self as u32) == *other
50+
}
51+
}
52+
impl PartialEq<i32> for u32 {
53+
fn eq(&self, other: &i32) -> bool {
54+
*other >= 0 && *self == *other as u32
55+
}
56+
}
57+
58+
// Our generic struct
59+
struct Foo<T> {
60+
value: T,
61+
}
62+
63+
// Manual impl of PartialEq for different generic params
64+
impl<T, U> PartialEq<Foo<U>> for Foo<T>
65+
where
66+
T: PartialEq<U>,
67+
{
68+
fn eq(&self, other: &Foo<U>) -> bool {
69+
self.value.eq(&other.value)
70+
}
71+
}
72+
73+
impl<T: PartialEq> Eq for Foo<T> {}
74+
75+
extern "C" {
76+
fn puts(s: *const i8);
77+
}
78+
79+
fn print(s: &str) {
80+
unsafe {
81+
puts(s as *const str as *const i8);
82+
}
83+
}
84+
85+
fn main() -> i32 {
86+
let a = Foo { value: 42i32 };
87+
let b = Foo { value: 42u32 };
88+
let c = Foo { value: 7u32 };
89+
90+
if a == b {
91+
print("a == b");
92+
} else {
93+
print("a != b");
94+
}
95+
96+
if a == c {
97+
print("a == c");
98+
} else {
99+
print("a != c");
100+
}
101+
102+
0
103+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/* { dg-output "a == b\r*\na != c\r*\n" }*/
2+
/* { dg-options "-w" } */
3+
4+
#[lang = "sized"]
5+
pub trait Sized {}
6+
7+
#[lang = "eq"]
8+
pub trait PartialEq<Rhs: ?Sized = Self> {
9+
fn eq(&self, other: &Rhs) -> bool;
10+
11+
fn ne(&self, other: &Rhs) -> bool {
12+
!self.eq(other)
13+
}
14+
}
15+
16+
impl PartialEq for i32 {
17+
fn eq(&self, other: &Self) -> bool {
18+
*self == *other
19+
}
20+
}
21+
22+
struct Foo<T> {
23+
value: T,
24+
}
25+
26+
impl<T: PartialEq> PartialEq for Foo<T> {
27+
fn eq(&self, other: &Self) -> bool {
28+
self.value.eq(&other.value)
29+
}
30+
}
31+
32+
extern "C" {
33+
fn puts(s: *const i8);
34+
}
35+
36+
fn print(s: &str) {
37+
unsafe {
38+
puts(s as *const str as *const i8);
39+
}
40+
}
41+
42+
fn main() -> i32 {
43+
let a = Foo { value: 42i32 };
44+
let b = Foo { value: 42i32 };
45+
let c = Foo { value: 99i32 };
46+
47+
if a == b {
48+
print("a == b");
49+
} else {
50+
print("a != b");
51+
}
52+
53+
if a == c {
54+
print("a == c");
55+
} else {
56+
print("a != c");
57+
}
58+
59+
0
60+
}

0 commit comments

Comments
 (0)