Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions gcc/rust/typecheck/rust-type-util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ query_type (HirId reference, TyTy::BaseType **result)
auto &resolver = *Resolver::get ();
TypeCheckContext *context = TypeCheckContext::get ();

if (context->query_in_progress (reference))
return false;

if (context->lookup_type (reference, result))
return true;

if (context->query_in_progress (reference))
return false;

context->insert_query (reference);

std::pair<HIR::Enum *, HIR::EnumItem *> enum_candidiate
Expand Down
176 changes: 176 additions & 0 deletions gcc/testsuite/rust/execute/torture/basic_partial_ord1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/* { dg-output "less\r*" }*/
mod core {
mod option {
pub enum Option<T> {
None,
Some(T),
}
}

mod marker {
#[lang = "phantom_data"]
pub struct PhantomData<T: ?Sized>;

#[lang = "structural_peq"]
pub trait StructuralPartialEq {}

#[lang = "structural_teq"]
pub trait StructuralEq {}

#[lang = "sized"]
pub trait Sized {}
}

mod cmp {
use super::marker::Sized;
use super::option::Option;

pub enum Ordering {
Less = -1,
Equal = 0,
Greater = 1,
}

#[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) {}
}

#[lang = "partial_ord"]
pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;

fn lt(&self, other: &Rhs) -> bool {
match self.partial_cmp(other) {
Option::Some(Ordering::Less) => true,
_ => false,
}
}

fn le(&self, other: &Rhs) -> bool {
match self.partial_cmp(other) {
Option::Some(Ordering::Less) | Option::Some(Ordering::Equal) => true,
_ => false,
}
}

fn gt(&self, other: &Rhs) -> bool {
match self.partial_cmp(other) {
Option::Some(Ordering::Greater) => true,
_ => false,
}
}

fn ge(&self, other: &Rhs) -> bool {
match self.partial_cmp(other) {
Option::Some(Ordering::Greater) | Option::Some(Ordering::Equal) => true,
_ => false,
}
}
}

pub trait Ord: Eq + PartialOrd<Self> {
fn cmp(&self, other: &Self) -> Ordering;
}
}
}

use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
use core::option::Option;

// Needed impls for primitives
impl PartialEq for i32 {
fn eq(&self, other: &Self) -> bool {
*self == *other
}
}

impl PartialOrd for i32 {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
if *self < *other {
Option::Some(Ordering::Less)
} else if *self > *other {
Option::Some(Ordering::Greater)
} else {
Option::Some(Ordering::Equal)
}
}
}

impl Eq for i32 {}
impl Ord for i32 {
fn cmp(&self, other: &Self) -> Ordering {
if *self < *other {
Ordering::Less
} else if *self > *other {
Ordering::Greater
} else {
Ordering::Equal
}
}
}

// Manual impl for struct Bar
struct Bar {
a: i32,
b: i32,
}

impl PartialEq for Bar {
fn eq(&self, other: &Self) -> bool {
self.a.eq(&other.a) && self.b.eq(&other.b)
}
}

impl Eq for Bar {}

impl PartialOrd for Bar {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
match self.a.partial_cmp(&other.a) {
Option::Some(Ordering::Equal) => self.b.partial_cmp(&other.b),
ord => ord,
}
}
}

impl Ord for Bar {
fn cmp(&self, other: &Self) -> Ordering {
match self.a.cmp(&other.a) {
Ordering::Equal => self.b.cmp(&other.b),
ord => ord,
}
}
}

// External print shim
extern "C" {
fn puts(s: *const i8);
}

fn print(s: &str) {
unsafe {
puts(s as *const str as *const i8);
}
}

fn main() -> i32 {
let x = Bar { a: 1, b: 2 };
let y = Bar { a: 1, b: 3 };

match x.partial_cmp(&y) {
Option::Some(Ordering::Less) => print("less"),
Option::Some(Ordering::Greater) => print("greater"),
Option::Some(Ordering::Equal) => print("equal"),
_ => print("none"),
}

0
}
184 changes: 184 additions & 0 deletions gcc/testsuite/rust/execute/torture/basic_partial_ord2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
/* { dg-output "<><=>=\r*" } */
/* { dg-options "-w" } */
mod core {
mod option {
pub enum Option<T> {
None,
Some(T),
}
}

mod marker {
#[lang = "phantom_data"]
pub struct PhantomData<T: ?Sized>;

#[lang = "structural_peq"]
pub trait StructuralPartialEq {}

#[lang = "structural_teq"]
pub trait StructuralEq {}

#[lang = "sized"]
pub trait Sized {}
}

mod cmp {
use super::marker::Sized;
use super::option::Option;

pub enum Ordering {
Less = -1,
Equal = 0,
Greater = 1,
}

#[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) {}
}

#[lang = "partial_ord"]
pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;

fn lt(&self, other: &Rhs) -> bool {
match self.partial_cmp(other) {
Option::Some(Ordering::Less) => true,
_ => false,
}
}

fn le(&self, other: &Rhs) -> bool {
match self.partial_cmp(other) {
Option::Some(Ordering::Less) | Option::Some(Ordering::Equal) => true,
_ => false,
}
}

fn gt(&self, other: &Rhs) -> bool {
match self.partial_cmp(other) {
Option::Some(Ordering::Greater) => true,
_ => false,
}
}

fn ge(&self, other: &Rhs) -> bool {
match self.partial_cmp(other) {
Option::Some(Ordering::Greater) | Option::Some(Ordering::Equal) => true,
_ => false,
}
}
}

pub trait Ord: Eq + PartialOrd<Self> {
fn cmp(&self, other: &Self) -> Ordering;
}
}
}

use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
use core::option::Option;

// Needed impls for primitives
impl PartialEq for i32 {
fn eq(&self, other: &Self) -> bool {
*self == *other
}
}

impl PartialOrd for i32 {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
if *self < *other {
Option::Some(Ordering::Less)
} else if *self > *other {
Option::Some(Ordering::Greater)
} else {
Option::Some(Ordering::Equal)
}
}
}

impl Eq for i32 {}
impl Ord for i32 {
fn cmp(&self, other: &Self) -> Ordering {
if *self < *other {
Ordering::Less
} else if *self > *other {
Ordering::Greater
} else {
Ordering::Equal
}
}
}

// Manual impl for struct Bar
struct Bar {
a: i32,
b: i32,
}

impl PartialEq for Bar {
fn eq(&self, other: &Self) -> bool {
self.a.eq(&other.a) && self.b.eq(&other.b)
}
}

impl Eq for Bar {}

impl PartialOrd for Bar {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
match self.a.partial_cmp(&other.a) {
Option::Some(Ordering::Equal) => self.b.partial_cmp(&other.b),
ord => ord,
}
}
}

impl Ord for Bar {
fn cmp(&self, other: &Self) -> Ordering {
match self.a.cmp(&other.a) {
Ordering::Equal => self.b.cmp(&other.b),
ord => ord,
}
}
}

// External print shim
extern "C" {
fn printf(s: *const i8);
}

fn print(s: &str) {
unsafe {
printf(s as *const str as *const i8);
}
}

fn main() -> i32 {
let a = Bar { a: 1, b: 2 };
let b = Bar { a: 1, b: 3 };
let c = Bar { a: 1, b: 2 };

if a < b {
print("<");
}
if b > a {
print(">");
}
if a <= c {
print("<=");
}
if b >= c {
print(">=");
}

0
}