aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/rust
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite/rust')
-rw-r--r--gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs2
-rw-r--r--gcc/testsuite/rust/compile/all-cast.rs2
-rw-r--r--gcc/testsuite/rust/compile/arrays2.rs3
-rw-r--r--gcc/testsuite/rust/compile/auto_traits2.rs2
-rw-r--r--gcc/testsuite/rust/compile/bad-rpit1.rs26
-rw-r--r--gcc/testsuite/rust/compile/bug-with-default-generic.rs15
-rw-r--r--gcc/testsuite/rust/compile/const3.rs2
-rw-r--r--gcc/testsuite/rust/compile/const_generics_10.rs32
-rw-r--r--gcc/testsuite/rust/compile/const_generics_11.rs14
-rw-r--r--gcc/testsuite/rust/compile/const_generics_12.rs14
-rw-r--r--gcc/testsuite/rust/compile/const_generics_13.rs11
-rw-r--r--gcc/testsuite/rust/compile/const_generics_14.rs13
-rw-r--r--gcc/testsuite/rust/compile/const_generics_15.rs16
-rw-r--r--gcc/testsuite/rust/compile/const_generics_16.rs10
-rw-r--r--gcc/testsuite/rust/compile/const_generics_3.rs25
-rw-r--r--gcc/testsuite/rust/compile/const_generics_5.rs4
-rw-r--r--gcc/testsuite/rust/compile/const_generics_8.rs7
-rw-r--r--gcc/testsuite/rust/compile/const_generics_9.rs13
-rw-r--r--gcc/testsuite/rust/compile/deferred_const_inference.rs7
-rw-r--r--gcc/testsuite/rust/compile/derive-debug1.rs6
-rw-r--r--gcc/testsuite/rust/compile/derive_macro1.rs2
-rw-r--r--gcc/testsuite/rust/compile/derive_partial_ord1.rs464
-rw-r--r--gcc/testsuite/rust/compile/enum_variant_name.rs2
-rw-r--r--gcc/testsuite/rust/compile/format_args_basic_expansion.rs1
-rw-r--r--gcc/testsuite/rust/compile/format_args_extra_comma.rs1
-rw-r--r--gcc/testsuite/rust/compile/generics8.rs2
-rw-r--r--gcc/testsuite/rust/compile/generics9.rs1
-rw-r--r--gcc/testsuite/rust/compile/glob_import_enum.rs16
-rw-r--r--gcc/testsuite/rust/compile/impl_trait_diag.rs17
-rw-r--r--gcc/testsuite/rust/compile/impl_trait_generic_arg.rs24
-rw-r--r--gcc/testsuite/rust/compile/invalid_label_name.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1048.rs8
-rw-r--r--gcc/testsuite/rust/compile/issue-1485.rs16
-rw-r--r--gcc/testsuite/rust/compile/issue-1487.rs15
-rw-r--r--gcc/testsuite/rust/compile/issue-2015.rs3
-rw-r--r--gcc/testsuite/rust/compile/issue-2043.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2166.rs2
-rw-r--r--gcc/testsuite/rust/compile/issue-2238.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-2680.rs6
-rw-r--r--gcc/testsuite/rust/compile/issue-2907.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-3144.rs29
-rw-r--r--gcc/testsuite/rust/compile/issue-3304.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-3454.rs20
-rw-r--r--gcc/testsuite/rust/compile/issue-3524.rs9
-rw-r--r--gcc/testsuite/rust/compile/issue-3525.rs6
-rw-r--r--gcc/testsuite/rust/compile/issue-3546.rs16
-rw-r--r--gcc/testsuite/rust/compile/issue-3551.rs15
-rw-r--r--gcc/testsuite/rust/compile/issue-3599.rs8
-rw-r--r--gcc/testsuite/rust/compile/issue-3618.rs2
-rw-r--r--gcc/testsuite/rust/compile/issue-3642.rs9
-rw-r--r--gcc/testsuite/rust/compile/issue-3660.rs3
-rw-r--r--gcc/testsuite/rust/compile/issue-3661.rs10
-rw-r--r--gcc/testsuite/rust/compile/issue-3671.rs2
-rw-r--r--gcc/testsuite/rust/compile/issue-3836.rs67
-rw-r--r--gcc/testsuite/rust/compile/issue-3874.rs4
-rw-r--r--gcc/testsuite/rust/compile/issue-3876.rs8
-rw-r--r--gcc/testsuite/rust/compile/issue-3885.rs7
-rw-r--r--gcc/testsuite/rust/compile/issue-3915.rs28
-rw-r--r--gcc/testsuite/rust/compile/issue-3916.rs36
-rw-r--r--gcc/testsuite/rust/compile/issue-3960.rs7
-rw-r--r--gcc/testsuite/rust/compile/issue-3978.rs8
-rw-r--r--gcc/testsuite/rust/compile/issue-4006.rs13
-rw-r--r--gcc/testsuite/rust/compile/loop_constant_context.rs5
-rw-r--r--gcc/testsuite/rust/compile/macros/builtin/recurse2.rs2
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs2
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-2.rs2
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/meta-param.rs7
-rw-r--r--gcc/testsuite/rust/compile/match-identifierpattern-enum.rs12
-rw-r--r--gcc/testsuite/rust/compile/match-identifierpattern.rs9
-rw-r--r--gcc/testsuite/rust/compile/match-restpattern-tuple-1.rs8
-rw-r--r--gcc/testsuite/rust/compile/match-restpattern-tuple-2.rs8
-rw-r--r--gcc/testsuite/rust/compile/match-slicepattern-array.rs8
-rw-r--r--gcc/testsuite/rust/compile/match-slicepattern-slice.rs10
-rw-r--r--gcc/testsuite/rust/compile/match-tuplestructpattern.rs9
-rw-r--r--gcc/testsuite/rust/compile/min_specialization1.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution10.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution11.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution12.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution13.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution14.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution15.rs1
-rw-r--r--gcc/testsuite/rust/compile/name_resolution16.rs1
-rw-r--r--gcc/testsuite/rust/compile/name_resolution17.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution18.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution2.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution20.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution22.rs1
-rw-r--r--gcc/testsuite/rust/compile/name_resolution23.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution24.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution25.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution4.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution6.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution7.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution8.rs2
-rw-r--r--gcc/testsuite/rust/compile/name_resolution9.rs2
-rw-r--r--gcc/testsuite/rust/compile/nested_macro_definition.rs2
-rw-r--r--gcc/testsuite/rust/compile/nr2/compile.exp149
-rw-r--r--gcc/testsuite/rust/compile/nr2/exclude17
-rw-r--r--gcc/testsuite/rust/compile/offset_of1.rs11
-rw-r--r--gcc/testsuite/rust/compile/offset_of2.rs9
-rw-r--r--gcc/testsuite/rust/compile/parse_simple_path_fail_1.rs3
-rw-r--r--gcc/testsuite/rust/compile/parse_simple_path_fail_2.rs9
-rw-r--r--gcc/testsuite/rust/compile/pub_restricted_1.rs6
-rw-r--r--gcc/testsuite/rust/compile/pub_restricted_2.rs8
-rw-r--r--gcc/testsuite/rust/compile/same_field_name.rs (renamed from gcc/testsuite/rust/execute/same_field_name.rs)2
-rw-r--r--gcc/testsuite/rust/compile/self-in-impl.rs15
-rw-r--r--gcc/testsuite/rust/compile/self_import_namespace.rs2
-rw-r--r--gcc/testsuite/rust/compile/silly-order-bug.rs8
-rw-r--r--gcc/testsuite/rust/compile/slicepattern-size-mismatch.rs8
-rw-r--r--gcc/testsuite/rust/compile/torture/extern_mod2.rs6
-rw-r--r--gcc/testsuite/rust/compile/torture/generics29.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics30.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/traits3.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/traits7.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/unended-raw-byte-string.rs6
-rw-r--r--gcc/testsuite/rust/compile/traits9.rs3
-rw-r--r--gcc/testsuite/rust/compile/try_block1.rs89
-rw-r--r--gcc/testsuite/rust/compile/tuple_mismatch.rs1
-rw-r--r--gcc/testsuite/rust/compile/unify-errors1.rs49
-rw-r--r--gcc/testsuite/rust/compile/use_1.rs1
-rw-r--r--gcc/testsuite/rust/compile/usize1.rs2
-rw-r--r--gcc/testsuite/rust/compile/while_let1.rs109
-rw-r--r--gcc/testsuite/rust/compile/while_let_without_label.rs11
-rw-r--r--gcc/testsuite/rust/compile/xfail/name_resolution21.rs2
-rw-r--r--gcc/testsuite/rust/execute/black_box.rs3
-rw-r--r--gcc/testsuite/rust/execute/execute.exp33
-rw-r--r--gcc/testsuite/rust/execute/inline_asm_inout_ident.rs23
-rw-r--r--gcc/testsuite/rust/execute/inline_asm_inout_var.rs24
-rw-r--r--gcc/testsuite/rust/execute/torture/basic_partial_ord1.rs189
-rw-r--r--gcc/testsuite/rust/execute/torture/basic_partial_ord2.rs197
-rw-r--r--gcc/testsuite/rust/execute/torture/builtin_abort.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/const-generics-1.rs24
-rw-r--r--gcc/testsuite/rust/execute/torture/const_block1.rs9
-rw-r--r--gcc/testsuite/rust/execute/torture/derive-partialeq2.rs80
-rw-r--r--gcc/testsuite/rust/execute/torture/for-loop1.rs38
-rw-r--r--gcc/testsuite/rust/execute/torture/for-loop2.rs38
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_desugar-2.rs32
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_desugar.rs32
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_rpit1.rs28
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_rpit2.rs36
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_rpit3.rs25
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_trait1.rs31
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_trait2.rs31
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_trait3.rs45
-rw-r--r--gcc/testsuite/rust/execute/torture/impl_trait4.rs31
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-1481.rs35
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-1482.rs23
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-2005.rs465
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-3836.rs454
-rw-r--r--gcc/testsuite/rust/execute/torture/iter1.rs38
-rw-r--r--gcc/testsuite/rust/execute/torture/match-identifierpattern.rs10
-rw-r--r--gcc/testsuite/rust/execute/torture/match-restpattern-tuple.rs27
-rw-r--r--gcc/testsuite/rust/execute/torture/match-slicepattern-array-1.rs23
-rw-r--r--gcc/testsuite/rust/execute/torture/match-slicepattern-slice-1.rs24
-rw-r--r--gcc/testsuite/rust/execute/torture/match-tuplestructpattern.rs12
-rw-r--r--gcc/testsuite/rust/execute/torture/min_specialization2.rs2
-rw-r--r--gcc/testsuite/rust/execute/torture/name_resolution.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/offset_of1.rs16
-rw-r--r--gcc/testsuite/rust/execute/torture/partial-eq-1.rs103
-rw-r--r--gcc/testsuite/rust/execute/torture/partial-eq-2.rs60
-rw-r--r--gcc/testsuite/rust/execute/torture/partial-eq-3.rs457
-rw-r--r--gcc/testsuite/rust/execute/torture/partial-eq-4.rs457
-rw-r--r--gcc/testsuite/rust/execute/torture/partial-ord-1.rs101
-rw-r--r--gcc/testsuite/rust/execute/torture/partial-ord-2.rs469
-rw-r--r--gcc/testsuite/rust/execute/torture/partial-ord-3.rs489
-rw-r--r--gcc/testsuite/rust/execute/torture/partial-ord-4.rs115
-rw-r--r--gcc/testsuite/rust/execute/torture/partial-ord-5.rs487
-rw-r--r--gcc/testsuite/rust/execute/torture/partial-ord-6.rs518
-rw-r--r--gcc/testsuite/rust/execute/torture/sip-hasher.rs438
-rw-r--r--gcc/testsuite/rust/execute/torture/struct-pattern-match.rs13
-rw-r--r--gcc/testsuite/rust/execute/torture/struct_pattern1.rs19
-rw-r--r--gcc/testsuite/rust/execute/torture/trait10.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/trait11.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/trait12.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/trait13.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/trait9.rs1
-rw-r--r--gcc/testsuite/rust/execute/xfail/match-identifierpattern-enum.rs15
177 files changed, 7261 insertions, 335 deletions
diff --git a/gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs b/gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs
index 6764f6e..1c49b75 100644
--- a/gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs
+++ b/gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs
@@ -1,5 +1,3 @@
-// { dg-additional-options "-frust-name-resolution-2.0" }
-
#![feature(optin_builtin_traits)]
pub unsafe auto trait Send {}
diff --git a/gcc/testsuite/rust/compile/all-cast.rs b/gcc/testsuite/rust/compile/all-cast.rs
index fa24373..6d8576c 100644
--- a/gcc/testsuite/rust/compile/all-cast.rs
+++ b/gcc/testsuite/rust/compile/all-cast.rs
@@ -4,7 +4,7 @@ fn main() {
0u32 as char; // { dg-error "cannot cast .u32. as .char., only .u8. can be cast as .char." }
- let x = &[1_usize, 2] as [usize]; // { dg-error "cast to unsized type: .& .usize:CAPACITY.. as ..usize.." }
+ let x = &[1_usize, 2] as [usize]; // { dg-error "cast to unsized type: .& .usize; 2.. as ..usize.." }
let a = &0u8; // Here, `x` is a `&u8`.
let y: u32 = a as u32; // { dg-error "casting .& u8. as .u32. is invalid" }
diff --git a/gcc/testsuite/rust/compile/arrays2.rs b/gcc/testsuite/rust/compile/arrays2.rs
index 668bcf0..1090059 100644
--- a/gcc/testsuite/rust/compile/arrays2.rs
+++ b/gcc/testsuite/rust/compile/arrays2.rs
@@ -1,5 +1,4 @@
-// { dg-additional-options "-w" }
fn main() {
let array: [i32; 5] = [1, 2, 3];
- // { dg-error "mismatched types, expected an array with a fixed size of 5 elements, found one with 3 elements" "" { target *-*-* } .-1 }
+ // { dg-error "mismatched types, expected ..i32; 5.. but got ...integer.; 3.. .E0308." "" { target *-*-* } .-1 }
}
diff --git a/gcc/testsuite/rust/compile/auto_traits2.rs b/gcc/testsuite/rust/compile/auto_traits2.rs
index 382d446..7004761 100644
--- a/gcc/testsuite/rust/compile/auto_traits2.rs
+++ b/gcc/testsuite/rust/compile/auto_traits2.rs
@@ -15,7 +15,7 @@ fn foo(a: &(dyn A + Send + Sync)) {
struct S;
impl A for S {
- fn a_method(&self) {} // { dg-warning "unused name" }
+ fn a_method(&self) {}
}
fn main() {
diff --git a/gcc/testsuite/rust/compile/bad-rpit1.rs b/gcc/testsuite/rust/compile/bad-rpit1.rs
new file mode 100644
index 0000000..d8c21b1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/bad-rpit1.rs
@@ -0,0 +1,26 @@
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+ fn id(&self) -> i32;
+}
+
+struct A;
+struct B;
+
+impl Foo for A {
+ fn id(&self) -> i32 {
+ 1
+ }
+}
+
+impl Foo for B {
+ fn id(&self) -> i32 {
+ 2
+ }
+}
+
+fn make_foo(cond: bool) -> impl Foo {
+ if cond { A } else { B }
+ // { dg-error "mismatched types, expected .A. but got .B. .E0308." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/bug-with-default-generic.rs b/gcc/testsuite/rust/compile/bug-with-default-generic.rs
new file mode 100644
index 0000000..25f46a0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/bug-with-default-generic.rs
@@ -0,0 +1,15 @@
+#[lang = "sized"]
+pub trait Sized {}
+
+pub trait MyBinaryTrait<Rhs = Self> {
+ fn do_something(&self, rhs: &Rhs);
+}
+
+struct Foo<T> {
+ // { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+ value: T,
+}
+
+impl<T> MyBinaryTrait for Foo<T> {
+ fn do_something(&self, _rhs: &Self) {}
+}
diff --git a/gcc/testsuite/rust/compile/const3.rs b/gcc/testsuite/rust/compile/const3.rs
index 22dc3d3..c1d0f29 100644
--- a/gcc/testsuite/rust/compile/const3.rs
+++ b/gcc/testsuite/rust/compile/const3.rs
@@ -3,5 +3,5 @@ fn size() -> usize {
}
fn main() {
- let a = [15; size()]; // { dg-error "only functions marked as .const. are allowed to be called from constant contexts" }
+ let a = [15; size()]; // { dg-error "calls in constants are limited to constant functions, tuple structs and tuple variants" }
}
diff --git a/gcc/testsuite/rust/compile/const_generics_10.rs b/gcc/testsuite/rust/compile/const_generics_10.rs
new file mode 100644
index 0000000..7e3bc86
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_10.rs
@@ -0,0 +1,32 @@
+#[lang = "sized"]
+trait Sized {}
+
+const M: usize = 4;
+
+struct Foo<T, const N: usize = 1> {
+ value: [T; N],
+}
+
+fn main() {
+ let foo = Foo::<i32> { value: [15] };
+ let foo = Foo::<i32, 2> { value: [15, 13] };
+ let foo: Foo<i32, 2> = Foo { value: [15, 13] };
+ let foo: Foo<i32, 2> = Foo::<i32, 2> { value: [15, 13] };
+ let foo: Foo<i32, { 1 + 1 }> = Foo { value: [15, 13] };
+ let foo = Foo::<i32, { 1 + 1 }> { value: [15, 13] };
+ let foo: Foo<i32, { 1 + 1 }> = Foo::<i32, { 1 + 1 }> { value: [15, 13] };
+ let foo: Foo<i32, M> = Foo::<i32, 4> {
+ value: [15, 13, 11, 9],
+ };
+
+ let invalid_foo: Foo<i32, { 1 + 1 }> = Foo::<i32, 3> { value: [15, 13] };
+ // { dg-error {mismatched types, expected ..T=i32; 3.. but got ...integer.; 2.. .E0308.} "" { target *-*-* } .-1 }
+ // { dg-error {mismatched types, expected ..T=i32; 2.. but got ..T=i32; 3.. .E0308.} "" { target *-*-* } .-2 }
+
+ let invalid_foo: Foo<i32, { 1 + 1 }> = Foo::<i32, M> { value: [15, 13] };
+ // { dg-error {mismatched types, expected ..T=i32; 4.. but got ...integer.; 2.. .E0308.} "" { target *-*-* } .-1 }
+ // { dg-error {mismatched types, expected ..T=i32; 2.. but got ..T=i32; 4.. .E0308.} "" { target *-*-* } .-2 }
+
+ let invalid_foo: Foo<i32> = Foo::<i32, 2> { value: [15, 13] };
+ // { dg-error {mismatched types, expected ..T=i32; 1.. but got ..T=i32; 2.. .E0308.} "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/const_generics_11.rs b/gcc/testsuite/rust/compile/const_generics_11.rs
new file mode 100644
index 0000000..de902ee
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_11.rs
@@ -0,0 +1,14 @@
+// { dg-options "-w" }
+
+#[lang = "sized"]
+trait Sized {}
+
+struct Matrix<T, const ROWS: usize, const COLS: usize> {
+ data: [[T; COLS]; ROWS],
+}
+
+fn main() {
+ let _: Matrix<u8, 2, 3> = Matrix {
+ data: [[1, 2, 3], [4, 5, 6]],
+ };
+}
diff --git a/gcc/testsuite/rust/compile/const_generics_12.rs b/gcc/testsuite/rust/compile/const_generics_12.rs
new file mode 100644
index 0000000..a17c525
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_12.rs
@@ -0,0 +1,14 @@
+// { dg-options "-w" }
+
+#[lang = "sized"]
+trait Sized {}
+
+const BASE: usize = 2;
+
+struct Foo<T, const N: usize> {
+ data: [T; N],
+}
+
+fn main() {
+ let _ = Foo::<u8, { BASE + 1 * 2 }> { data: [0; 4] };
+}
diff --git a/gcc/testsuite/rust/compile/const_generics_13.rs b/gcc/testsuite/rust/compile/const_generics_13.rs
new file mode 100644
index 0000000..20dd0b90
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_13.rs
@@ -0,0 +1,11 @@
+#[lang = "sized"]
+trait Sized {}
+
+struct Foo<T, const N: usize> {
+ value: [T; N],
+}
+
+fn main() {
+ let foo: Foo<_, _>;
+ // { dg-error {type provided when a constant was expected .E0747.} "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/const_generics_14.rs b/gcc/testsuite/rust/compile/const_generics_14.rs
new file mode 100644
index 0000000..4d52efb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_14.rs
@@ -0,0 +1,13 @@
+#[lang = "sized"]
+trait Sized {}
+
+type MyLen = usize;
+struct Foo<T, const N: usize> {
+ data: [T; N],
+}
+
+fn main() {
+ let _ = Foo::<u8, MyLen> { data: [1, 2, 3] };
+ // { dg-error {type provided when a constant was expected .E0747.} "" { target *-*-* } .-1 }
+ // { dg-error {expected an ADT type for constructor} "" { target *-*-* } .-2 }
+}
diff --git a/gcc/testsuite/rust/compile/const_generics_15.rs b/gcc/testsuite/rust/compile/const_generics_15.rs
new file mode 100644
index 0000000..a160abf
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_15.rs
@@ -0,0 +1,16 @@
+#[lang = "sized"]
+trait Sized {}
+
+enum Foo<const N: usize> {
+ A([u8; N]),
+}
+
+union Bar<const N: usize> {
+ a: [i32; N],
+ b: [u8; N],
+}
+
+fn main() {
+ let _ = Foo::<4>::A([1, 2, 3, 4]);
+ let _ = Bar::<4> { a: [0; 4] };
+}
diff --git a/gcc/testsuite/rust/compile/const_generics_16.rs b/gcc/testsuite/rust/compile/const_generics_16.rs
new file mode 100644
index 0000000..060dbda
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_16.rs
@@ -0,0 +1,10 @@
+#[lang = "sized"]
+trait Sized {}
+
+struct Foo<T = u8, const N: usize = 4> {
+ data: [T; N], // { dg-warning "field is never read: .data." }
+}
+
+fn main() {
+ let _x = Foo { data: [1, 2, 3, 4] };
+}
diff --git a/gcc/testsuite/rust/compile/const_generics_3.rs b/gcc/testsuite/rust/compile/const_generics_3.rs
index 524d48d..3415f17 100644
--- a/gcc/testsuite/rust/compile/const_generics_3.rs
+++ b/gcc/testsuite/rust/compile/const_generics_3.rs
@@ -1,28 +1,21 @@
-// { dg-additional-options "-w -frust-name-resolution-2.0" }
-
#[lang = "sized"]
trait Sized {}
const M: usize = 4;
struct Foo<T, const N: usize = 1> {
- value: [T; N],
+ value: [T; N], // { dg-warning "field is never read: .value." }
}
fn main() {
- let foo = Foo::<i32> { value: [15] };
- let foo = Foo::<i32, 2> { value: [15, 13] };
- let foo: Foo<i32, 2> = Foo { value: [15, 13] };
- let foo: Foo<i32, 2> = Foo::<i32, 2> { value: [15, 13] };
- let foo: Foo<i32, { 1 + 1 }> = Foo { value: [15, 13] };
- let foo = Foo::<i32, { 1 + 1 }> { value: [15, 13] };
- let foo: Foo<i32, { 1 + 1 }> = Foo::<i32, { 1 + 1 }> { value: [15, 13] };
- let foo: Foo<i32, M> = Foo::<i32, 4> {
+ let _foo = Foo::<i32> { value: [15] };
+ let _foo = Foo::<i32, 2> { value: [15, 13] };
+ let _foo: Foo<i32, 2> = Foo { value: [15, 13] };
+ let _foo: Foo<i32, 2> = Foo::<i32, 2> { value: [15, 13] };
+ let _foo: Foo<i32, { 1 + 1 }> = Foo { value: [15, 13] };
+ let _foo = Foo::<i32, { 1 + 1 }> { value: [15, 13] };
+ let _foo: Foo<i32, { 1 + 1 }> = Foo::<i32, { 1 + 1 }> { value: [15, 13] };
+ let _foo: Foo<i32, M> = Foo::<i32, 4> {
value: [15, 13, 11, 9],
};
-
- // FIXME: Add proper const typecheck errors here
- let invalid_foo: Foo<i32, { 1 + 1 }> = Foo::<i32, 3> { value: [15, 13] };
- let invalid_foo: Foo<i32, { 1 + 1 }> = Foo::<i32, M> { value: [15, 13] };
- let invalid_foo: Foo<i32> = Foo::<i32, 2> { value: [15, 13] };
}
diff --git a/gcc/testsuite/rust/compile/const_generics_5.rs b/gcc/testsuite/rust/compile/const_generics_5.rs
index 685229e..4d05569 100644
--- a/gcc/testsuite/rust/compile/const_generics_5.rs
+++ b/gcc/testsuite/rust/compile/const_generics_5.rs
@@ -1,4 +1,3 @@
-// { dg-options "-w" }
struct Foo<const N: usize = { 14 }>;
const M: usize = 15;
@@ -8,5 +7,6 @@ fn main() {
let _: Foo<15> = Foo;
let _: Foo<{ M }> = Foo;
let _: Foo<M> = Foo;
- // let _: Foo<N> = Foo; this causes an ICE we need to do const generics
+ let _: Foo<N> = Foo;
+ // { dg-error {type provided when a constant was expected .E0747.} "" { target *-*-* } .-1 }
}
diff --git a/gcc/testsuite/rust/compile/const_generics_8.rs b/gcc/testsuite/rust/compile/const_generics_8.rs
index bb34652..ce5e1b5 100644
--- a/gcc/testsuite/rust/compile/const_generics_8.rs
+++ b/gcc/testsuite/rust/compile/const_generics_8.rs
@@ -9,12 +9,13 @@ type Bipboupe<const N: i32 = 15> = Bidule;
trait Fooable<const N: i32 = 15> {}
union Bidoulepe<const N: i32 = 15> {
- // { dg-error "default values for const generic parameters are not allowed in .union. items" "" {target *-*-* } .-1 }
int: i32,
float: f32,
}
-fn const_default<const N: i32 = 15>() {} // { dg-error "default values for const generic parameters are not allowed in .function. items" }
+fn const_default<const N: i32 = 15>() {} // { dg-error "default values for const generic parameters are not allowed here" }
// Note - missing generic parameter - needs name resolution on const generics
-impl<const N: i32 = 15> Bidule {} // { dg-error "default values for const generic parameters are not allowed in .impl. items" }
+impl<const N: i32 = 15> Bidule {}
+// { dg-error "default values for const generic parameters are not allowed here" "" {target *-*-* } .-1 }
+// { dg-error "unconstrained type parameter" "" {target *-*-* } .-2 }
diff --git a/gcc/testsuite/rust/compile/const_generics_9.rs b/gcc/testsuite/rust/compile/const_generics_9.rs
new file mode 100644
index 0000000..98e2d3f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_9.rs
@@ -0,0 +1,13 @@
+// { dg-options "-w" }
+
+#[lang = "sized"]
+trait Sized {}
+
+struct ArrayWrapper<T, const N: usize> {
+ data: [T; N],
+}
+
+pub fn test() -> [u8; 4] {
+ let a = ArrayWrapper { data: [1u8; 4] };
+ a.data
+}
diff --git a/gcc/testsuite/rust/compile/deferred_const_inference.rs b/gcc/testsuite/rust/compile/deferred_const_inference.rs
new file mode 100644
index 0000000..25a3b17
--- /dev/null
+++ b/gcc/testsuite/rust/compile/deferred_const_inference.rs
@@ -0,0 +1,7 @@
+// { dg-additional-options "-frust-compile-until=typecheck" }
+
+// #![feature(generic_arg_infer)]
+
+fn main() {
+ let a: [u32; _] = [15u32];
+}
diff --git a/gcc/testsuite/rust/compile/derive-debug1.rs b/gcc/testsuite/rust/compile/derive-debug1.rs
index cf2187d..5927374 100644
--- a/gcc/testsuite/rust/compile/derive-debug1.rs
+++ b/gcc/testsuite/rust/compile/derive-debug1.rs
@@ -23,15 +23,15 @@ mod core {
}
}
-#[derive(Debug)] // { dg-warning "unused name" }
+#[derive(Debug)]
// { dg-warning "stub implementation" "" { target *-*-* } .-1 }
struct Foo { a: i32, b: i64 } // { dg-warning "is never constructed" }
-#[derive(Debug)] // { dg-warning "unused name" }
+#[derive(Debug)]
// { dg-warning "stub implementation" "" { target *-*-* } .-1 }
struct Bar(i32, i32); // { dg-warning "is never constructed" }
-#[derive(Debug)] // { dg-warning "unused name" }
+#[derive(Debug)]
// { dg-warning "stub implementation" "" { target *-*-* } .-1 }
enum Baz {
A,
diff --git a/gcc/testsuite/rust/compile/derive_macro1.rs b/gcc/testsuite/rust/compile/derive_macro1.rs
index bc10d60..8c42aba 100644
--- a/gcc/testsuite/rust/compile/derive_macro1.rs
+++ b/gcc/testsuite/rust/compile/derive_macro1.rs
@@ -7,7 +7,7 @@ pub trait Clone {
}
// This warning can be removed once we properly handle implems with #[automatically_derived]
-#[derive(Clone)] // { dg-warning "unused name .self." }
+#[derive(Clone)]
pub struct S;
fn main() {
diff --git a/gcc/testsuite/rust/compile/derive_partial_ord1.rs b/gcc/testsuite/rust/compile/derive_partial_ord1.rs
new file mode 100644
index 0000000..eeca62d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/derive_partial_ord1.rs
@@ -0,0 +1,464 @@
+// { dg-additional-options "-w" }
+
+#![feature(intrinsics)]
+
+mod core {
+ mod option {
+ // #[rustc_diagnostic_item = "option_type"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Option<T> {
+ /// No value
+ #[lang = "None"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ None,
+ /// Some value `T`
+ #[lang = "Some"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+ }
+ }
+
+ mod marker {
+ #[lang = "phantom_data"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`")]
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {
+ // Empty.
+ }
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(Eq)]`")]
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {
+ // Empty.
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[lang = "sized"]
+ // #[rustc_on_unimplemented(
+ // message = "the size for values of type `{Self}` cannot be known at compilation time",
+ // label = "doesn't have a size known at compile-time"
+ // )]
+ // #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
+ // #[rustc_specialization_trait]
+ pub trait Sized {
+ // Empty.
+ }
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ // #[derive(Clone, Copy, PartialEq, Debug, Hash)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Ordering {
+ /// An ordering where a compared value is less than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Less = -1,
+ /// An ordering where a compared value is equal to another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Equal = 0,
+ /// An ordering where a compared value is greater than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} == {Rhs}`"
+ // )]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Eq: PartialEq<Self> {
+ // this method is used solely by #[deriving] to assert
+ // that every component of a type implements #[deriving]
+ // itself, the current deriving infrastructure means doing this
+ // assertion without using a method on this trait is nearly
+ // impossible.
+ //
+ // This should never be implemented by hand.
+ #[doc(hidden)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+
+ #[lang = "partial_ord"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`"
+ // )]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ /// This method returns an ordering between `self` and `other` values if one exists.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// let result = 1.0.partial_cmp(&2.0);
+ /// assert_eq!(result, Some(Ordering::Less));
+ ///
+ /// let result = 1.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Equal));
+ ///
+ /// let result = 2.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Greater));
+ /// ```
+ ///
+ /// When comparison is impossible:
+ ///
+ /// ```
+ /// let result = f64::NAN.partial_cmp(&1.0);
+ /// assert_eq!(result, None);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+ /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 < 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 < 1.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn lt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 <= 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 <= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn le(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 > 2.0;
+ /// assert_eq!(result, false);
+ ///
+ /// let result = 2.0 > 2.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn gt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 2.0 >= 1.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 >= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ge(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+ }
+
+ #[doc(alias = "<")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Ord: Eq + PartialOrd<Self> {
+ /// This method returns an [`Ordering`] between `self` and `other`.
+ ///
+ /// By convention, `self.cmp(&other)` returns the ordering matching the expression
+ /// `self <operator> other` if true.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// assert_eq!(5.cmp(&10), Ordering::Less);
+ /// assert_eq!(10.cmp(&5), Ordering::Greater);
+ /// assert_eq!(5.cmp(&5), Ordering::Equal);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn cmp(&self, other: &Self) -> Ordering;
+
+ /// Compares and returns the maximum of two values.
+ ///
+ /// Returns the second argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(2, 1.max(2));
+ /// assert_eq!(2, 2.max(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn max(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Compares and returns the minimum of two values.
+ ///
+ /// Returns the first argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(1, 1.min(2));
+ /// assert_eq!(2, 2.min(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn min(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Restrict a value to a certain interval.
+ ///
+ /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
+ /// less than `min`. Otherwise this returns `self`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `min > max`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(clamp)]
+ ///
+ /// assert!((-3).clamp(-2, 1) == -2);
+ /// assert!(0.clamp(-2, 1) == 0);
+ /// assert!(2.clamp(-2, 1) == 1);
+ /// ```
+ #[must_use]
+ #[unstable(feature = "clamp", issue = "44095")]
+ fn clamp(self, min: Self, max: Self) -> Self
+ where
+ Self: Sized,
+ {
+ if self < min {
+ min
+ } else if self > max {
+ max
+ } else {
+ self
+ }
+ }
+ }
+ }
+
+ pub mod intrinsics {
+ #[lang = "discriminant_kind"]
+ pub trait DiscriminantKind {
+ #[lang = "discriminant_type"]
+ type Discriminant;
+ }
+
+ extern "rust-intrinsic" {
+ pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+ }
+ }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+// for comparing discriminant_value
+impl PartialEq for isize {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+// for comparing discriminant_value
+impl PartialOrd for isize {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+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::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl Ord for i32 {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self > *other {
+ Ordering::Greater
+ } else if *self < *other {
+ Ordering::Less
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+impl Eq for i32 {}
+
+#[derive(PartialEq, PartialOrd)]
+enum Foo {
+ A,
+ B(i32, i32, i32),
+ C { inner: i32, outer: i32 },
+}
+
+#[derive(Ord, PartialOrd, PartialEq, Eq)]
+struct Bar {
+ a: i32,
+}
+
+#[derive(Ord, PartialOrd, PartialEq, Eq)]
+struct BarFull {
+ a: i32,
+ b: i32,
+ c: i32,
+ d: i32,
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() {
+ let a = Foo::A;
+ let b = Foo::B(15, 14, 13);
+
+ match a.partial_cmp(&b) {
+ Option::Some(Ordering::Less) => print("less"),
+ Option::Some(Ordering::Greater) => print("greater"),
+ Option::Some(Ordering::Equal) => print("equal"),
+ _ => print("uuuuh woops lol"),
+ }
+}
diff --git a/gcc/testsuite/rust/compile/enum_variant_name.rs b/gcc/testsuite/rust/compile/enum_variant_name.rs
index 671fced..965acd1 100644
--- a/gcc/testsuite/rust/compile/enum_variant_name.rs
+++ b/gcc/testsuite/rust/compile/enum_variant_name.rs
@@ -1,4 +1,4 @@
-// { dg-additional-options "-w -frust-name-resolution-2.0" }
+// { dg-additional-options "-w" }
struct E1;
enum Test {
diff --git a/gcc/testsuite/rust/compile/format_args_basic_expansion.rs b/gcc/testsuite/rust/compile/format_args_basic_expansion.rs
index 40bcd3c..cedb62c 100644
--- a/gcc/testsuite/rust/compile/format_args_basic_expansion.rs
+++ b/gcc/testsuite/rust/compile/format_args_basic_expansion.rs
@@ -35,7 +35,6 @@ pub mod core {
impl Display for i32 {
fn fmt(&self, _: &mut Formatter) -> Result {
- // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
Result
}
}
diff --git a/gcc/testsuite/rust/compile/format_args_extra_comma.rs b/gcc/testsuite/rust/compile/format_args_extra_comma.rs
index fcc435c..dc48a3a 100644
--- a/gcc/testsuite/rust/compile/format_args_extra_comma.rs
+++ b/gcc/testsuite/rust/compile/format_args_extra_comma.rs
@@ -35,7 +35,6 @@ pub mod core {
impl Display for i32 {
fn fmt(&self, _: &mut Formatter) -> Result {
- // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
Result
}
}
diff --git a/gcc/testsuite/rust/compile/generics8.rs b/gcc/testsuite/rust/compile/generics8.rs
index 88c4bac..2d30a9e 100644
--- a/gcc/testsuite/rust/compile/generics8.rs
+++ b/gcc/testsuite/rust/compile/generics8.rs
@@ -4,7 +4,7 @@ pub trait Sized {}
struct Foo<A, B>(A, B);
impl<T> Foo<i32, T> {
- fn test(a: T) -> T {
+ fn test(a: T) -> T { // { dg-error "duplicate definitions with name .test." }
a
}
}
diff --git a/gcc/testsuite/rust/compile/generics9.rs b/gcc/testsuite/rust/compile/generics9.rs
index 56c6198..949fbb1 100644
--- a/gcc/testsuite/rust/compile/generics9.rs
+++ b/gcc/testsuite/rust/compile/generics9.rs
@@ -1,4 +1,3 @@
-// { dg-additional-options "-frust-name-resolution-2.0" }
struct Foo<A, B = (A, B)>(A, B);
// { dg-error "type parameters with a default cannot use forward declared identifiers" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/glob_import_enum.rs b/gcc/testsuite/rust/compile/glob_import_enum.rs
new file mode 100644
index 0000000..032a1db
--- /dev/null
+++ b/gcc/testsuite/rust/compile/glob_import_enum.rs
@@ -0,0 +1,16 @@
+use self::Ordering::*;
+use Ordering::*;
+
+enum Ordering {
+ A,
+ B,
+}
+
+fn foo(_: Ordering) {}
+
+fn main() {
+ let a = A;
+
+ foo(a);
+ foo(B);
+}
diff --git a/gcc/testsuite/rust/compile/impl_trait_diag.rs b/gcc/testsuite/rust/compile/impl_trait_diag.rs
new file mode 100644
index 0000000..54a0cd2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/impl_trait_diag.rs
@@ -0,0 +1,17 @@
+#[lang = "sized"]
+pub trait Sized {}
+
+trait Foo {
+ fn method(&self);
+}
+
+struct Bar;
+impl Foo for Bar {}
+
+fn main() {
+ let x: impl Foo = Bar; // { dg-error ".impl Trait. not allowed outside of function and inherent method return types .E0562." }
+
+ struct Wrapper {
+ field: impl Foo, // { dg-error ".impl Trait. not allowed outside of function and inherent method return types .E0562." }
+ }
+}
diff --git a/gcc/testsuite/rust/compile/impl_trait_generic_arg.rs b/gcc/testsuite/rust/compile/impl_trait_generic_arg.rs
new file mode 100644
index 0000000..ecdb088
--- /dev/null
+++ b/gcc/testsuite/rust/compile/impl_trait_generic_arg.rs
@@ -0,0 +1,24 @@
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+ fn id(&self) -> u8;
+}
+
+struct Bar;
+
+impl Foo for Bar {
+ fn id(&self) -> u8 {
+ 1
+ }
+}
+
+fn takes(val: impl Foo) -> u8 {
+ val.id()
+}
+
+fn main() {
+ let b = Bar;
+ let x = takes::<Bar>(b);
+ // { dg-error "cannot provide explicit generic arguments when .impl Trait. is used in argument position .E0632." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/invalid_label_name.rs b/gcc/testsuite/rust/compile/invalid_label_name.rs
index 66e40a6..d1c5a33 100644
--- a/gcc/testsuite/rust/compile/invalid_label_name.rs
+++ b/gcc/testsuite/rust/compile/invalid_label_name.rs
@@ -1,4 +1,3 @@
-// { dg-additional-options "-frust-name-resolution-2.0" }
pub fn function() {
'continue: loop {
// { dg-error "invalid label name .'continue." "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/issue-1048.rs b/gcc/testsuite/rust/compile/issue-1048.rs
new file mode 100644
index 0000000..8d4053a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1048.rs
@@ -0,0 +1,8 @@
+macro_rules! maybe_return { ($e:expr) => ($e); }
+
+fn frob(x: i32) -> i32{
+ maybe_return! {x}
+ // { dg-error "mismatched types. expected .... but got .i32. .E0308." "" { target *-*-* } .-1 }
+ // should return -1
+ -1
+}
diff --git a/gcc/testsuite/rust/compile/issue-1485.rs b/gcc/testsuite/rust/compile/issue-1485.rs
new file mode 100644
index 0000000..a0cd5a0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1485.rs
@@ -0,0 +1,16 @@
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+ #[lang = "fn_once_output"]
+ type Output;
+
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+struct BinOpInvalid {
+ lhs: i32,
+ rhs: i32,
+ f: impl FnOnce(i32) -> i32, // { dg-error ".impl Trait. not allowed outside of function and inherent method return types .E0562." }
+}
diff --git a/gcc/testsuite/rust/compile/issue-1487.rs b/gcc/testsuite/rust/compile/issue-1487.rs
new file mode 100644
index 0000000..4a4d759
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1487.rs
@@ -0,0 +1,15 @@
+// { dg-options "-w" }
+#[lang = "sized"]
+trait Sized {}
+
+trait Printable {
+ fn print(&self);
+}
+
+struct Foo;
+
+impl Printable for Foo {
+ fn print(&self) {}
+}
+
+fn take_printable(_: impl Printable) {}
diff --git a/gcc/testsuite/rust/compile/issue-2015.rs b/gcc/testsuite/rust/compile/issue-2015.rs
index 7789ecd..7e03651 100644
--- a/gcc/testsuite/rust/compile/issue-2015.rs
+++ b/gcc/testsuite/rust/compile/issue-2015.rs
@@ -1,4 +1,5 @@
-// { dg-additional-options "-frust-compile-until=lowering" }
+#[lang = "sized"]
+trait Sized {}
macro_rules! impl_foo {
() => { impl Foo }
diff --git a/gcc/testsuite/rust/compile/issue-2043.rs b/gcc/testsuite/rust/compile/issue-2043.rs
index efa1ded..92532b7 100644
--- a/gcc/testsuite/rust/compile/issue-2043.rs
+++ b/gcc/testsuite/rust/compile/issue-2043.rs
@@ -6,7 +6,6 @@ struct Foo<'a> {
impl<'a> Foo<'a> {
fn bar(self: &mut Foo<'a>) {}
// { dg-warning "associated function is never used: .bar." "" { target *-*-* } .-1 }
- // { dg-warning "unused name .self." "" { target *-*-* } .-2 }
}
fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-2166.rs b/gcc/testsuite/rust/compile/issue-2166.rs
index 318f0a6..142ed17 100644
--- a/gcc/testsuite/rust/compile/issue-2166.rs
+++ b/gcc/testsuite/rust/compile/issue-2166.rs
@@ -11,7 +11,6 @@ impl Add for u32 {
type Output = u32;
fn add(self) -> u32 {
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
0
}
}
@@ -20,7 +19,6 @@ impl<'a> Add for &'a u32 {
type Output = u32;
fn add(self) -> <u32 as Add>::Output {
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
0
}
}
diff --git a/gcc/testsuite/rust/compile/issue-2238.rs b/gcc/testsuite/rust/compile/issue-2238.rs
index 38871b3..6a43a13 100644
--- a/gcc/testsuite/rust/compile/issue-2238.rs
+++ b/gcc/testsuite/rust/compile/issue-2238.rs
@@ -10,7 +10,6 @@ fn main() {
impl Bar for Foo {
fn foo(&self) {}
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
}
let s = Foo;
diff --git a/gcc/testsuite/rust/compile/issue-2680.rs b/gcc/testsuite/rust/compile/issue-2680.rs
new file mode 100644
index 0000000..d5ae2ff44
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2680.rs
@@ -0,0 +1,6 @@
+// { dg-additional-options "-fdump-tree-gimple" }
+pub fn test_cast() {
+ let i = 1;
+ // { dg-final { scan-tree-dump-times {const i32 i;} 1 gimple } }
+ let _j = i as i64;
+}
diff --git a/gcc/testsuite/rust/compile/issue-2907.rs b/gcc/testsuite/rust/compile/issue-2907.rs
index 1af843f..fdf1953 100644
--- a/gcc/testsuite/rust/compile/issue-2907.rs
+++ b/gcc/testsuite/rust/compile/issue-2907.rs
@@ -15,7 +15,6 @@ impl<B: Bar> Foo for B {
type Ty = u32;
fn foo(self) -> Self::Ty {
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
14
}
}
diff --git a/gcc/testsuite/rust/compile/issue-3144.rs b/gcc/testsuite/rust/compile/issue-3144.rs
new file mode 100644
index 0000000..4e61078
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3144.rs
@@ -0,0 +1,29 @@
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "copy"]
+trait Copy {}
+
+#[lang = "clone"]
+pub trait Clone {
+ fn clone(&self) -> Self;
+}
+
+impl Clone for i32 {
+ fn clone(&self) -> i32 {
+ *self
+ }
+}
+
+struct S {}
+
+#[derive(Clone, Copy)]
+// { dg-error {bounds not satisfied for S .Clone. is not satisfied .E0277.} "" { target *-*-* } .-1 }
+struct S2 {
+ a: i32,
+ s: S,
+}
+
+fn main() -> i32 {
+ 0
+}
diff --git a/gcc/testsuite/rust/compile/issue-3304.rs b/gcc/testsuite/rust/compile/issue-3304.rs
index 6ab614f..cc376fa 100644
--- a/gcc/testsuite/rust/compile/issue-3304.rs
+++ b/gcc/testsuite/rust/compile/issue-3304.rs
@@ -1,4 +1,3 @@
-// { dg-additional-options "-frust-name-resolution-2.0" }
#[lang = "sized"]
trait Sized {}
diff --git a/gcc/testsuite/rust/compile/issue-3454.rs b/gcc/testsuite/rust/compile/issue-3454.rs
new file mode 100644
index 0000000..2a3c0c7
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3454.rs
@@ -0,0 +1,20 @@
+#[lang = "sized"]
+pub trait Sized {}
+
+macro_rules! impl_foo {
+ () => { impl Foo }
+}
+
+pub trait Foo {}
+
+pub trait Bar {
+ type Baz;
+}
+
+pub fn foo(_value: impl Bar<Baz = impl_foo!()>) -> i32 {
+ 15
+}
+
+pub fn bar(_value: impl Bar<Baz = impl Foo>) -> i32 {
+ 16
+}
diff --git a/gcc/testsuite/rust/compile/issue-3524.rs b/gcc/testsuite/rust/compile/issue-3524.rs
new file mode 100644
index 0000000..62c8c35
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3524.rs
@@ -0,0 +1,9 @@
+struct A {}
+// { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+
+impl A {
+ fn main() {}
+ // { dg-warning "associated function is never used: .main." "" { target *-*-* } .-1 }
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-3525.rs b/gcc/testsuite/rust/compile/issue-3525.rs
new file mode 100644
index 0000000..84a7ebe
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3525.rs
@@ -0,0 +1,6 @@
+// { dg-options "-w" }
+
+struct Foo(usize);
+
+const B: usize = A.0;
+const A: Foo = Foo(123);
diff --git a/gcc/testsuite/rust/compile/issue-3546.rs b/gcc/testsuite/rust/compile/issue-3546.rs
new file mode 100644
index 0000000..d4ec0bb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3546.rs
@@ -0,0 +1,16 @@
+const L: usize = 3;
+
+fn main() {
+ let p = Printer {};
+ p.print();
+}
+
+trait Print<const N: usize> {
+ fn print(&self) -> usize {
+ 3
+ }
+}
+
+struct Printer {}
+impl Print<L> for Printer {}
+// { dg-error "generic item takes at most 1 type arguments but 1 were supplied" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/issue-3551.rs b/gcc/testsuite/rust/compile/issue-3551.rs
new file mode 100644
index 0000000..6d6a812
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3551.rs
@@ -0,0 +1,15 @@
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+ #[lang = "fn_once_output"]
+ type Output;
+
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+struct Bug {
+ a: [(); (|| 0)()],
+ // { dg-error "calls in constants are limited to constant functions, tuple structs and tuple variants" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3599.rs b/gcc/testsuite/rust/compile/issue-3599.rs
new file mode 100644
index 0000000..1d29fac
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3599.rs
@@ -0,0 +1,8 @@
+#[lang = "sized"]
+trait Sized {}
+
+trait Bar {}
+
+struct S; // { dg-warning "struct is never constructed" }
+
+pub fn test(foo: impl Bar) {}
diff --git a/gcc/testsuite/rust/compile/issue-3618.rs b/gcc/testsuite/rust/compile/issue-3618.rs
new file mode 100644
index 0000000..3bf2c7e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3618.rs
@@ -0,0 +1,2 @@
+static _X : ()
+ = loop{}; // { dg-error "'loop' is not allowed in const context" }
diff --git a/gcc/testsuite/rust/compile/issue-3642.rs b/gcc/testsuite/rust/compile/issue-3642.rs
new file mode 100644
index 0000000..6d9decc
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3642.rs
@@ -0,0 +1,9 @@
+#[lang = "sized"]
+trait Sized {}
+
+pub trait T<X> {
+ const D: i32 = {
+ // { dg-error "mismatched types, expected .i32. but got .()." "" { target *-*-* } .-1 }
+ const C: X;
+ };
+}
diff --git a/gcc/testsuite/rust/compile/issue-3660.rs b/gcc/testsuite/rust/compile/issue-3660.rs
new file mode 100644
index 0000000..1f1c583
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3660.rs
@@ -0,0 +1,3 @@
+pub static A: [u32; 2] = [1, 2];
+
+pub static B: [u8; 2] = [3, 4];
diff --git a/gcc/testsuite/rust/compile/issue-3661.rs b/gcc/testsuite/rust/compile/issue-3661.rs
new file mode 100644
index 0000000..8d03c36
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3661.rs
@@ -0,0 +1,10 @@
+pub macro m($inner_str:expr) {
+ #[m = $inner_str]
+ // { dg-error "macro not found" "" { target *-*-* } .-1 }
+
+ struct S;
+}
+
+fn main() {
+ m!(stringify!(foo));
+}
diff --git a/gcc/testsuite/rust/compile/issue-3671.rs b/gcc/testsuite/rust/compile/issue-3671.rs
index e800d53..8015653 100644
--- a/gcc/testsuite/rust/compile/issue-3671.rs
+++ b/gcc/testsuite/rust/compile/issue-3671.rs
@@ -1,2 +1,2 @@
-impl Self<0> {}
+impl Foo<0> {}
// { dg-error "could not resolve type path" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/issue-3836.rs b/gcc/testsuite/rust/compile/issue-3836.rs
new file mode 100644
index 0000000..a228795
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3836.rs
@@ -0,0 +1,67 @@
+// { dg-options "-w" }
+mod core {
+ mod option {
+ pub enum Option<T> {
+ #[lang = "None"]
+ None,
+ #[lang = "Some"]
+ Some(T),
+ }
+ }
+
+ mod marker {
+ #[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)
+ }
+ }
+
+ #[lang = "partial_ord"]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+ }
+ }
+}
+
+use core::cmp::{Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ false
+ }
+}
+
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ Option::Some(Ordering::Equal)
+ }
+}
+
+struct Foo {
+ a: i32,
+}
+
+impl PartialEq for Foo {
+ fn eq(&self, other: &'_ Self) -> bool {
+ ::core::cmp::PartialEq::eq(&self.a, &other.a)
+ }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3874.rs b/gcc/testsuite/rust/compile/issue-3874.rs
new file mode 100644
index 0000000..ebce4b6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3874.rs
@@ -0,0 +1,4 @@
+fn wow(){
+ &#[serde]
+ // { dg-error "found unexpected token .#. in null denotation" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3876.rs b/gcc/testsuite/rust/compile/issue-3876.rs
new file mode 100644
index 0000000..17b1590
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3876.rs
@@ -0,0 +1,8 @@
+enum test {
+ A(i32),
+}
+
+fn fun(x: i32) {
+ test::A { x }
+ // { dg-error "unknown field" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3885.rs b/gcc/testsuite/rust/compile/issue-3885.rs
new file mode 100644
index 0000000..050a59c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3885.rs
@@ -0,0 +1,7 @@
+pub fn test() {
+ let _u: [_; _] = [15u32];
+ let _v: [u8; _] = [1, 2, 3];
+ let _w: [_; 2] = [1.0, 2.0];
+ let _x = [42; 5];
+ let _y: [_; _] = _x;
+}
diff --git a/gcc/testsuite/rust/compile/issue-3915.rs b/gcc/testsuite/rust/compile/issue-3915.rs
new file mode 100644
index 0000000..7132036
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3915.rs
@@ -0,0 +1,28 @@
+// { dg-options "-w" }
+#[lang = "sized"]
+trait Sized {}
+
+trait Trait {
+ fn do_thing();
+}
+
+struct MyType;
+
+impl Trait for MyType {
+ fn do_thing() {}
+}
+
+struct Wrapper<T: Trait> {
+ value: T,
+}
+
+impl<T: Trait> Wrapper<T> {
+ fn call_it() {
+ T::do_thing();
+ }
+}
+
+fn main() {
+ let _ = Wrapper::<MyType> { value: MyType };
+ Wrapper::<MyType>::call_it();
+}
diff --git a/gcc/testsuite/rust/compile/issue-3916.rs b/gcc/testsuite/rust/compile/issue-3916.rs
new file mode 100644
index 0000000..59b522b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3916.rs
@@ -0,0 +1,36 @@
+#![feature(rustc_attrs)]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "add"]
+trait Add<Rhs = Self> {
+ type Output;
+
+ fn add(self, rhs: Rhs) -> Self::Output;
+}
+
+macro_rules! add_impl {
+ ($($t:ty)*) => ($(
+ impl Add for $t {
+ type Output = $t;
+
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ fn add(self, other: $t) -> $t { self + other }
+ }
+ )*)
+}
+
+add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
+
+pub fn test(len: usize) -> u64 {
+ let mut i = 0;
+ let mut out = 0;
+ if i + 3 < len {
+ out = 123;
+ } else {
+ out = 456;
+ }
+ out
+}
diff --git a/gcc/testsuite/rust/compile/issue-3960.rs b/gcc/testsuite/rust/compile/issue-3960.rs
new file mode 100644
index 0000000..57329f0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3960.rs
@@ -0,0 +1,7 @@
+fn main() {
+ struct G {
+ g: (),
+ }
+ let g = [0; G { g: () }];
+ // { dg-error "mismatched types, expected .usize. but got .G. .E0308." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3978.rs b/gcc/testsuite/rust/compile/issue-3978.rs
new file mode 100644
index 0000000..4f17d3d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3978.rs
@@ -0,0 +1,8 @@
+type Dimension = usize;
+
+pub fn main() {}
+
+mod m2 {
+ fn main() {}
+ // { dg-warning "function is never used" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-4006.rs b/gcc/testsuite/rust/compile/issue-4006.rs
new file mode 100644
index 0000000..328c7b6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4006.rs
@@ -0,0 +1,13 @@
+#![feature(rustc_attrs)]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+ () => {};
+}
+
+pub fn main() {
+ asm!(
+ "xor eax, eax"
+ "xor eax, eax");
+ // { dg-error "expected token .;." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/loop_constant_context.rs b/gcc/testsuite/rust/compile/loop_constant_context.rs
new file mode 100644
index 0000000..ed0782b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/loop_constant_context.rs
@@ -0,0 +1,5 @@
+// { dg-error "'loop' is not allowed in const context" "" { target *-*-* } .+1 }
+const CONST_LOOP : () = loop{};
+
+// { dg-error "'loop' is not allowed in const context" "" { target *-*-* } .+1 }
+static STATIC_LOOP : () = loop{}; \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/macros/builtin/recurse2.rs b/gcc/testsuite/rust/compile/macros/builtin/recurse2.rs
index 73e6ab4..fbb4b10 100644
--- a/gcc/testsuite/rust/compile/macros/builtin/recurse2.rs
+++ b/gcc/testsuite/rust/compile/macros/builtin/recurse2.rs
@@ -34,7 +34,7 @@ fn print_str(s: &str) {
}
}
-// { dg-final { scan-assembler {"abheyho"} } }
+// { dg-final { scan-assembler {"abheyho(\\0)?"} } }
static S: &str = concat!("a", 'b', a!(), a!(b c d e f a!()), '\0');
fn main() {
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs
index e5b38bb..bcbc8dd 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs
@@ -1,4 +1,4 @@
-// { dg-additional-options "-frust-name-resolution-2.0 -frust-compile-until=lowering" }
+// { dg-additional-options "-frust-compile-until=lowering" }
macro_rules! impl_fn_for_zst {
($(
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-2.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-2.rs
index cfc8ab4..47514f1 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-2.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-2.rs
@@ -1,4 +1,4 @@
-// { dg-additional-options "-frust-name-resolution-2.0 -frust-compile-until=lowering" }
+// { dg-additional-options "-frust-compile-until=lowering" }
macro_rules! impl_fn_for_zst {
($(
diff --git a/gcc/testsuite/rust/compile/macros/mbe/meta-param.rs b/gcc/testsuite/rust/compile/macros/mbe/meta-param.rs
new file mode 100644
index 0000000..ed6e100
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macros/mbe/meta-param.rs
@@ -0,0 +1,7 @@
+macro_rules! foo {
+ ($x:meta) => {0}
+}
+
+pub fn main() -> i32 {
+ foo!(Clone)
+}
diff --git a/gcc/testsuite/rust/compile/match-identifierpattern-enum.rs b/gcc/testsuite/rust/compile/match-identifierpattern-enum.rs
new file mode 100644
index 0000000..c712667
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-identifierpattern-enum.rs
@@ -0,0 +1,12 @@
+enum Foo {
+ I(i32),
+}
+
+fn main() {
+ let x = Foo::I(1);
+
+ match x {
+ a @ Foo::I(b) => {},
+ _ => {},
+ };
+}
diff --git a/gcc/testsuite/rust/compile/match-identifierpattern.rs b/gcc/testsuite/rust/compile/match-identifierpattern.rs
new file mode 100644
index 0000000..6c558ac
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-identifierpattern.rs
@@ -0,0 +1,9 @@
+fn main() {
+ let x = 1;
+
+ match x {
+ 2 => {},
+ a @ 3 => {},
+ _ => {},
+ }
+}
diff --git a/gcc/testsuite/rust/compile/match-restpattern-tuple-1.rs b/gcc/testsuite/rust/compile/match-restpattern-tuple-1.rs
new file mode 100644
index 0000000..5cce3c4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-restpattern-tuple-1.rs
@@ -0,0 +1,8 @@
+fn main() {
+ let x = (1, 2, 3, 4);
+
+ match x {
+ (1, .., 4) => {},
+ _ => {}
+ }
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/match-restpattern-tuple-2.rs b/gcc/testsuite/rust/compile/match-restpattern-tuple-2.rs
new file mode 100644
index 0000000..40900a3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-restpattern-tuple-2.rs
@@ -0,0 +1,8 @@
+fn main() {
+ let x = (1, 2, 3, 4);
+
+ match x {
+ (1, .., 2, 3, 4, 5) => {}, // { dg-error "expected a tuple with 4 elements, found one with 5 elements" }
+ _ => {}
+ }
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/match-slicepattern-array.rs b/gcc/testsuite/rust/compile/match-slicepattern-array.rs
new file mode 100644
index 0000000..e48ca75
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-slicepattern-array.rs
@@ -0,0 +1,8 @@
+fn main() {
+ let a = [0, 1];
+
+ match a {
+ [0, 1] => {},
+ _ => {}
+ }
+}
diff --git a/gcc/testsuite/rust/compile/match-slicepattern-slice.rs b/gcc/testsuite/rust/compile/match-slicepattern-slice.rs
new file mode 100644
index 0000000..cc33d93
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-slicepattern-slice.rs
@@ -0,0 +1,10 @@
+fn main() {
+ let arr = [1, 2];
+ let slice: &[i32] = &arr;
+
+ match slice {
+ [1] => {},
+ [_, 2] => {},
+ _ => {}
+ }
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/match-tuplestructpattern.rs b/gcc/testsuite/rust/compile/match-tuplestructpattern.rs
new file mode 100644
index 0000000..0dae71e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-tuplestructpattern.rs
@@ -0,0 +1,9 @@
+fn main() {
+ struct A (i32, i32);
+ let a = A (0, 1);
+
+ match a {
+ A (0, 1) => {},
+ _ => {}
+ }
+}
diff --git a/gcc/testsuite/rust/compile/min_specialization1.rs b/gcc/testsuite/rust/compile/min_specialization1.rs
index d38167e..ba97f87 100644
--- a/gcc/testsuite/rust/compile/min_specialization1.rs
+++ b/gcc/testsuite/rust/compile/min_specialization1.rs
@@ -9,7 +9,7 @@ pub trait Foo {
pub struct Bar;
impl Foo for Bar {
- default fn foo(&self) -> bool { // { dg-warning "unused" }
+ default fn foo(&self) -> bool {
true
}
}
diff --git a/gcc/testsuite/rust/compile/name_resolution10.rs b/gcc/testsuite/rust/compile/name_resolution10.rs
index 33643bd..f156f98 100644
--- a/gcc/testsuite/rust/compile/name_resolution10.rs
+++ b/gcc/testsuite/rust/compile/name_resolution10.rs
@@ -1,4 +1,4 @@
-// { dg-options "-frust-name-resolution-2.0 -frust-compile-until=lowering" }
+// { dg-options "-frust-compile-until=lowering" }
#![feature(decl_macro)]
diff --git a/gcc/testsuite/rust/compile/name_resolution11.rs b/gcc/testsuite/rust/compile/name_resolution11.rs
index a464d2a..329567a 100644
--- a/gcc/testsuite/rust/compile/name_resolution11.rs
+++ b/gcc/testsuite/rust/compile/name_resolution11.rs
@@ -1,4 +1,4 @@
-// { dg-additional-options "-frust-name-resolution-2.0 -frust-compile-until=lowering" }
+// { dg-additional-options "-frust-compile-until=lowering" }
fn foo() {
let b = 10;
fn bar() {
diff --git a/gcc/testsuite/rust/compile/name_resolution12.rs b/gcc/testsuite/rust/compile/name_resolution12.rs
index 9cce31c..0f217aa 100644
--- a/gcc/testsuite/rust/compile/name_resolution12.rs
+++ b/gcc/testsuite/rust/compile/name_resolution12.rs
@@ -1,4 +1,4 @@
-// { dg-additional-options "-frust-name-resolution-2.0 -frust-compile-until=lowering" }
+// { dg-additional-options "-frust-compile-until=lowering" }
const TOTO: i32 = 10;
diff --git a/gcc/testsuite/rust/compile/name_resolution13.rs b/gcc/testsuite/rust/compile/name_resolution13.rs
index 33edbf9..8356cf6 100644
--- a/gcc/testsuite/rust/compile/name_resolution13.rs
+++ b/gcc/testsuite/rust/compile/name_resolution13.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
pub mod foo {
pub macro bar() {}
}
diff --git a/gcc/testsuite/rust/compile/name_resolution14.rs b/gcc/testsuite/rust/compile/name_resolution14.rs
index eaef6a5..44c43aa 100644
--- a/gcc/testsuite/rust/compile/name_resolution14.rs
+++ b/gcc/testsuite/rust/compile/name_resolution14.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
pub mod foo {
pub macro bar() {}
}
diff --git a/gcc/testsuite/rust/compile/name_resolution15.rs b/gcc/testsuite/rust/compile/name_resolution15.rs
index 45f38da..e82c90e 100644
--- a/gcc/testsuite/rust/compile/name_resolution15.rs
+++ b/gcc/testsuite/rust/compile/name_resolution15.rs
@@ -1,4 +1,3 @@
-// { dg-additional-options "-frust-name-resolution-2.0" }
#![feature(decl_macro)]
pub mod foo {
diff --git a/gcc/testsuite/rust/compile/name_resolution16.rs b/gcc/testsuite/rust/compile/name_resolution16.rs
index 230722e..4db7b2e 100644
--- a/gcc/testsuite/rust/compile/name_resolution16.rs
+++ b/gcc/testsuite/rust/compile/name_resolution16.rs
@@ -1,4 +1,3 @@
-// { dg-additional-options "-frust-name-resolution-2.0" }
#![feature(decl_macro)]
pub mod foo {
diff --git a/gcc/testsuite/rust/compile/name_resolution17.rs b/gcc/testsuite/rust/compile/name_resolution17.rs
index 4859476..84ad380 100644
--- a/gcc/testsuite/rust/compile/name_resolution17.rs
+++ b/gcc/testsuite/rust/compile/name_resolution17.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
struct Foo;
fn Foo() {} // { dg-error ".Foo. defined multiple times" }
diff --git a/gcc/testsuite/rust/compile/name_resolution18.rs b/gcc/testsuite/rust/compile/name_resolution18.rs
index 5940149..17a3352 100644
--- a/gcc/testsuite/rust/compile/name_resolution18.rs
+++ b/gcc/testsuite/rust/compile/name_resolution18.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
struct Marker;
struct Foo {
diff --git a/gcc/testsuite/rust/compile/name_resolution2.rs b/gcc/testsuite/rust/compile/name_resolution2.rs
index 7e4f5a1..564c5d2 100644
--- a/gcc/testsuite/rust/compile/name_resolution2.rs
+++ b/gcc/testsuite/rust/compile/name_resolution2.rs
@@ -4,7 +4,7 @@ pub trait Sized {}
struct Bar;
trait Foo {
- fn bar(&self) {} // { dg-warning "unused name" }
+ fn bar(&self) {}
}
pub fn outer() {
diff --git a/gcc/testsuite/rust/compile/name_resolution20.rs b/gcc/testsuite/rust/compile/name_resolution20.rs
index e6c2dd5..f131bb4 100644
--- a/gcc/testsuite/rust/compile/name_resolution20.rs
+++ b/gcc/testsuite/rust/compile/name_resolution20.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
pub mod foo {
pub macro bar() {}
}
diff --git a/gcc/testsuite/rust/compile/name_resolution22.rs b/gcc/testsuite/rust/compile/name_resolution22.rs
index c49331e..bb5edda 100644
--- a/gcc/testsuite/rust/compile/name_resolution22.rs
+++ b/gcc/testsuite/rust/compile/name_resolution22.rs
@@ -1,4 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
struct Marker;
struct Foo(Marker);
diff --git a/gcc/testsuite/rust/compile/name_resolution23.rs b/gcc/testsuite/rust/compile/name_resolution23.rs
index 50b8e81..843be2a 100644
--- a/gcc/testsuite/rust/compile/name_resolution23.rs
+++ b/gcc/testsuite/rust/compile/name_resolution23.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
mod a {
pub mod b {
pub fn foo() {}
diff --git a/gcc/testsuite/rust/compile/name_resolution24.rs b/gcc/testsuite/rust/compile/name_resolution24.rs
index f4eb7b2..4350cd8 100644
--- a/gcc/testsuite/rust/compile/name_resolution24.rs
+++ b/gcc/testsuite/rust/compile/name_resolution24.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
mod a {
pub mod b {
pub fn baz() {}
diff --git a/gcc/testsuite/rust/compile/name_resolution25.rs b/gcc/testsuite/rust/compile/name_resolution25.rs
index 3cacac7..0cadd9e 100644
--- a/gcc/testsuite/rust/compile/name_resolution25.rs
+++ b/gcc/testsuite/rust/compile/name_resolution25.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
struct Test; // { dg-warning "struct is never constructed: .Test." }
impl Test {}
diff --git a/gcc/testsuite/rust/compile/name_resolution4.rs b/gcc/testsuite/rust/compile/name_resolution4.rs
index b2eadbe..0fc72f6 100644
--- a/gcc/testsuite/rust/compile/name_resolution4.rs
+++ b/gcc/testsuite/rust/compile/name_resolution4.rs
@@ -2,7 +2,7 @@
pub trait Sized {}
trait Foo {
- fn foo(&self) {} // { dg-warning "unused name" }
+ fn foo(&self) {}
}
struct Bar;
diff --git a/gcc/testsuite/rust/compile/name_resolution6.rs b/gcc/testsuite/rust/compile/name_resolution6.rs
index e4087e6..b2b5f6b 100644
--- a/gcc/testsuite/rust/compile/name_resolution6.rs
+++ b/gcc/testsuite/rust/compile/name_resolution6.rs
@@ -1,4 +1,4 @@
-// { dg-options "-frust-name-resolution-2.0 -frust-compile-until=lowering" }
+// { dg-options "-frust-compile-until=lowering" }
pub mod foo {
pub mod bar {
diff --git a/gcc/testsuite/rust/compile/name_resolution7.rs b/gcc/testsuite/rust/compile/name_resolution7.rs
index fa84e2f..78cb0b2 100644
--- a/gcc/testsuite/rust/compile/name_resolution7.rs
+++ b/gcc/testsuite/rust/compile/name_resolution7.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
// check that macros by example do not get inserted in ribs like regular items
pub mod foo {
pub mod bar {
diff --git a/gcc/testsuite/rust/compile/name_resolution8.rs b/gcc/testsuite/rust/compile/name_resolution8.rs
index 6fb5170..aca1945 100644
--- a/gcc/testsuite/rust/compile/name_resolution8.rs
+++ b/gcc/testsuite/rust/compile/name_resolution8.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
// check that macros by example get exported to the crate's root with #[macro_export]
pub mod foo {
pub mod bar {
diff --git a/gcc/testsuite/rust/compile/name_resolution9.rs b/gcc/testsuite/rust/compile/name_resolution9.rs
index 792b3bd..84ba3c5 100644
--- a/gcc/testsuite/rust/compile/name_resolution9.rs
+++ b/gcc/testsuite/rust/compile/name_resolution9.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
pub mod foo {
pub mod bar {
fn f() {
diff --git a/gcc/testsuite/rust/compile/nested_macro_definition.rs b/gcc/testsuite/rust/compile/nested_macro_definition.rs
index c0b7250..b71afbd 100644
--- a/gcc/testsuite/rust/compile/nested_macro_definition.rs
+++ b/gcc/testsuite/rust/compile/nested_macro_definition.rs
@@ -1,5 +1,3 @@
-// { dg-options "-frust-name-resolution-2.0" }
-
macro_rules! toto {
() => {
macro_rules! tata {
diff --git a/gcc/testsuite/rust/compile/nr2/compile.exp b/gcc/testsuite/rust/compile/nr2/compile.exp
deleted file mode 100644
index 9e15cdd..0000000
--- a/gcc/testsuite/rust/compile/nr2/compile.exp
+++ /dev/null
@@ -1,149 +0,0 @@
-# Copyright (C) 2021-2024 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GCC; see the file COPYING3. If not see
-# <http://www.gnu.org/licenses/>.
-
-# Run compile tests with name resolution 2.0 enabled
-
-# Load support procs.
-load_lib rust-dg.exp
-
-# These tests don't run runtest_file_p consistently if it
-# doesn't return the same values, so disable parallelization
-# of this *.exp file. The first parallel runtest to reach
-# this will run all the tests serially.
-if ![gcc_parallel_test_run_p compile] {
- return
-}
-gcc_parallel_test_enable 0
-
-# Initialize `dg'.
-dg-init
-
-namespace eval rust-nr2-ns {
- # Exclude tests which aren't passing yet
- # These should be removed from the exclude file over time
-
- set exclude_fh [open $srcdir/$subdir/exclude r]
- set exclude_raw [lsort [split [read $exclude_fh] "\n"]]
- close $exclude_fh
- unset exclude_fh
-
- set exclude ""
- foreach ent $exclude_raw {
- if [regexp {^[^#].*} $ent] {
- lappend exclude $ent
- }
- }
- unset exclude_raw
-
- # Run tests in directories
- # Manually specifying these, in case some other test file
- # does something weird
- set test_dirs {{} {macros builtin} {macros mbe} {macros proc} {torture}}
-
- set tests_expect_ok ""
- set tests_expect_err ""
-
- set compile_dir [list {*}[file split $srcdir] {*}[file split $subdir]]
- set compile_dir [lreplace $compile_dir end end]
-
- foreach test_dir $test_dirs {
- foreach test [lsort [glob -nocomplain -tails -directory [file join {*}$compile_dir {*}$test_dir] *.rs]] {
- # use '/' as the path seperator for entries in the exclude file
- set test_lbl [join [list {*}$test_dir $test] "/"]
- set idx [lsearch -exact -sorted $exclude $test_lbl]
- if {$idx == -1} {
- if {[runtest_file_p $runtests [file join {*}$compile_dir {*}$test_dir $test]]} {
- lappend tests_expect_ok [list {*}$test_dir $test]
- }
- } else {
- if {[runtest_file_p $runtests [file join {*}$compile_dir {*}$test_dir $test]]} {
- lappend tests_expect_err [list {*}$test_dir $test]
- }
- set exclude [lreplace $exclude $idx $idx]
- }
- }
- }
-
- # Generate failures for unmatched tests in the exclude list
- foreach ent $exclude {
- fail "$ent: could not exclude test"
- }
- unset exclude
-
- # run a test while catching record_test calls
- set record_test_out ""
- proc try_test { test } {
- variable record_test_out
- rename ::record_test record_test_old
-
- proc ::record_test { type msg args } {
- namespace eval ::rust-nr2-ns {
- set type [uplevel 1 {set type}]
- set msg [uplevel 1 {set msg}]
- variable record_test_out
- switch $type {
- FAIL {
- lappend record_test_out [list $type $msg]
- }
- XPASS {
- lappend record_test_out [list $type $msg]
- }
- }
- }
- }
-
- namespace eval :: {
- set saved-dg-do-what-default ${dg-do-what-default}
- set dg-do-what-default "compile"
- dg-runtest [list [uplevel 1 {set test}]] "-frust-name-resolution-2.0" ""
- set dg-do-what-default ${saved-dg-do-what-default}
- }
-
- rename ::record_test ""
- rename record_test_old ::record_test
-
- set record_test_cache $record_test_out
- set record_test_out ""
- return $record_test_cache
- }
-
- # check for unexpected failures
- foreach test $tests_expect_ok {
- set fails [try_test [file join {*}$compile_dir {*}$test]]
- if {[llength $fails] != 0} {
- foreach ent $fails {
- record_test [lindex $ent 0] "on nr2: [lindex $ent 1]"
- }
- } else {
- record_test PASS "[file join {*}$test] on nr2"
- }
- }
-
- #check for unexpected successes
- foreach test $tests_expect_err {
- set fails [try_test [file join {*}$compile_dir {*}$test]]
- if {[llength $fails] == 0} {
- record_test XPASS "[file join {*}$test] on nr2"
- } else {
- record_test XFAIL "[file join {*}$test] on nr2 was rightfully excluded"
- }
- }
-}
-
-# All done.
-dg-finish
-
-gcc_parallel_test_enable 1
diff --git a/gcc/testsuite/rust/compile/nr2/exclude b/gcc/testsuite/rust/compile/nr2/exclude
deleted file mode 100644
index c020e36..0000000
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ /dev/null
@@ -1,17 +0,0 @@
-canonical_paths1.rs
-issue-3315-2.rs
-privacy5.rs
-privacy8.rs
-pub_restricted_1.rs
-pub_restricted_2.rs
-pub_restricted_3.rs
-issue-2905-2.rs
-derive-default1.rs
-derive-eq-invalid.rs
-torture/alt_patterns1.rs
-torture/name_resolve1.rs
-issue-3663.rs
-issue-3671.rs
-issue-3652.rs
-issue-3649.rs
-# please don't delete the trailing newline
diff --git a/gcc/testsuite/rust/compile/offset_of1.rs b/gcc/testsuite/rust/compile/offset_of1.rs
new file mode 100644
index 0000000..5b79699
--- /dev/null
+++ b/gcc/testsuite/rust/compile/offset_of1.rs
@@ -0,0 +1,11 @@
+// { dg-additional-options "-frust-compile-until=lowering -frust-assume-builtin-offset-of" }
+
+pub struct Foo {
+ a: i32,
+}
+
+fn main() {
+ let _ = offset_of!(Foo, a); // valid
+ let _ = offset_of!("bloop", a); // { dg-error "could not parse type" }
+ let _ = offset_of!(Foo, 15); // { dg-error "could not parse field" }
+}
diff --git a/gcc/testsuite/rust/compile/offset_of2.rs b/gcc/testsuite/rust/compile/offset_of2.rs
new file mode 100644
index 0000000..d4ad9c2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/offset_of2.rs
@@ -0,0 +1,9 @@
+// { dg-additional-options "-frust-compile-until=compilation -frust-assume-builtin-offset-of" }
+
+pub struct Foo {
+ a: i32,
+}
+
+fn main() {
+ let _ = offset_of!(Foo, a); // valid
+}
diff --git a/gcc/testsuite/rust/compile/parse_simple_path_fail_1.rs b/gcc/testsuite/rust/compile/parse_simple_path_fail_1.rs
new file mode 100644
index 0000000..c112e40
--- /dev/null
+++ b/gcc/testsuite/rust/compile/parse_simple_path_fail_1.rs
@@ -0,0 +1,3 @@
+pub(in crate::) struct S;
+// { dg-error "expecting ... but .::. found" "" { target *-*-* } .-1 }
+// { dg-error "failed to parse item in crate" "" { target *-*-* } .-2 }
diff --git a/gcc/testsuite/rust/compile/parse_simple_path_fail_2.rs b/gcc/testsuite/rust/compile/parse_simple_path_fail_2.rs
new file mode 100644
index 0000000..94c49c3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/parse_simple_path_fail_2.rs
@@ -0,0 +1,9 @@
+mod A {
+ struct B;
+}
+
+use A{B};
+// { dg-error "unexpected token" "" { target *-*-* } .-1 }
+// { dg-error "could not parse use tree" "" { target *-*-* } .-2 }
+// { dg-error "failed to parse item in crate" "" { target *-*-* } 10 }
+// ^^^ TODO: should the above error happen at line 10?
diff --git a/gcc/testsuite/rust/compile/pub_restricted_1.rs b/gcc/testsuite/rust/compile/pub_restricted_1.rs
index 9bda968..2afbeb4 100644
--- a/gcc/testsuite/rust/compile/pub_restricted_1.rs
+++ b/gcc/testsuite/rust/compile/pub_restricted_1.rs
@@ -6,8 +6,8 @@ pub mod foo {
}
}
-pub(in foo::fah::baz) struct A1; // { dg-error "cannot find simple path segment .fah." }
-pub(in fro::bulator::saindoux) struct A2; // { dg-error "cannot find simple path segment .fro." }
-pub(in foo::bar::saindoux) struct A3; // { dg-error "cannot find simple path segment .saindoux." }
+pub(in foo::fah::baz) struct A1; // { dg-error "could not resolve path .foo::fah::baz." }
+pub(in fro::bulator::saindoux) struct A2; // { dg-error "could not resolve path .fro::bulator::saindoux." }
+pub(in foo::bar::saindoux) struct A3; // { dg-error "could not resolve path .foo::bar::saindoux." }
fn main() {}
diff --git a/gcc/testsuite/rust/compile/pub_restricted_2.rs b/gcc/testsuite/rust/compile/pub_restricted_2.rs
index 8588f27..fea9379 100644
--- a/gcc/testsuite/rust/compile/pub_restricted_2.rs
+++ b/gcc/testsuite/rust/compile/pub_restricted_2.rs
@@ -3,16 +3,16 @@
mod foo {
mod bar {
mod baz {
- pub(in baz) struct A0;
- pub(in bar::baz) struct A1;
+ pub(in super::baz) struct A0;
+ pub(in super::super::bar::baz) struct A1;
pub(in foo::bar::baz) struct A2;
mod sain {
mod doux {}
}
- pub(in sain) struct A3; // { dg-error "restricted path is not an ancestor of the current module" }
- pub(in sain::doux) struct A4; // { dg-error "restricted path is not an ancestor of the current module" }
+ pub(in self::sain) struct A3; // { dg-error "restricted path is not an ancestor of the current module" }
+ pub(in self::sain::doux) struct A4; // { dg-error "restricted path is not an ancestor of the current module" }
}
}
}
diff --git a/gcc/testsuite/rust/execute/same_field_name.rs b/gcc/testsuite/rust/compile/same_field_name.rs
index d57562b..8e5b78c 100644
--- a/gcc/testsuite/rust/execute/same_field_name.rs
+++ b/gcc/testsuite/rust/compile/same_field_name.rs
@@ -1,7 +1,7 @@
// https://doc.rust-lang.org/error_codes/E0124.html
fn main() {
struct Foo {
- field1: i32, // { dg-error "field .field1. is already declared" }
+ field1: i32,
field1: i32, // { dg-error "field .field1. is already declared" }
field1: i32, // { dg-error "field .field1. is already declared" }
}
diff --git a/gcc/testsuite/rust/compile/self-in-impl.rs b/gcc/testsuite/rust/compile/self-in-impl.rs
new file mode 100644
index 0000000..a567897
--- /dev/null
+++ b/gcc/testsuite/rust/compile/self-in-impl.rs
@@ -0,0 +1,15 @@
+// the error message here is what rustc >=1.66 emits
+// rustc <1.66 emits a "cycle detected" error when
+// trying to calculate the impl type
+//
+// since we aren't trying to match error messages too closely
+// and the >=1.66 error message is nicer
+// we may as well mimic that
+
+impl ((Self, i32)) {}
+// { dg-error ".Self. is not valid in the self" "" { target *-*-* } .-1 }
+
+trait Foo {}
+
+impl Foo for ((Self, i32)) {}
+// { dg-error ".Self. is not valid in the self" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/self_import_namespace.rs b/gcc/testsuite/rust/compile/self_import_namespace.rs
index 2d9b2ed..a63c1d7 100644
--- a/gcc/testsuite/rust/compile/self_import_namespace.rs
+++ b/gcc/testsuite/rust/compile/self_import_namespace.rs
@@ -1,5 +1,3 @@
-// { dg-additional-options "-frust-name-resolution-2.0" }
-
mod bar {
pub mod foo {}
pub fn foo() {}
diff --git a/gcc/testsuite/rust/compile/silly-order-bug.rs b/gcc/testsuite/rust/compile/silly-order-bug.rs
new file mode 100644
index 0000000..0d9cf1d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/silly-order-bug.rs
@@ -0,0 +1,8 @@
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+ type Output;
+}
diff --git a/gcc/testsuite/rust/compile/slicepattern-size-mismatch.rs b/gcc/testsuite/rust/compile/slicepattern-size-mismatch.rs
new file mode 100644
index 0000000..b54b532
--- /dev/null
+++ b/gcc/testsuite/rust/compile/slicepattern-size-mismatch.rs
@@ -0,0 +1,8 @@
+fn main() {
+ let arr = [0, 1];
+
+ match arr {
+ [0, 1, 2] => {} // { dg-error "pattern requires 3 elements but array has 2 .E0527." }
+ _ => {}
+ }
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/torture/extern_mod2.rs b/gcc/testsuite/rust/compile/torture/extern_mod2.rs
index 4984d5d..f3a4f79 100644
--- a/gcc/testsuite/rust/compile/torture/extern_mod2.rs
+++ b/gcc/testsuite/rust/compile/torture/extern_mod2.rs
@@ -12,6 +12,12 @@ mod no_leading_equal;
#[path = "modules/valid_path.rs"]
mod extra_spaces;
+#[path = ""] // { dg-error "path attributes must contain a filename" }
+mod empty_path; // { dg-error "no candidate found" }
+
+#[path = " "] // { dg-error "path attributes must contain a filename" }
+mod path_with_spaces; // { dg-error "no candidate found" }
+
#[path] // { dg-error "path attributes must contain a filename" }
mod error; // { dg-error "no candidate found" }
diff --git a/gcc/testsuite/rust/compile/torture/generics29.rs b/gcc/testsuite/rust/compile/torture/generics29.rs
index e9c693e..baf53e4 100644
--- a/gcc/testsuite/rust/compile/torture/generics29.rs
+++ b/gcc/testsuite/rust/compile/torture/generics29.rs
@@ -5,7 +5,6 @@ struct Foo<A, B>(A, B);
impl Foo<i32, f32> {
fn test<X>(self, a: X) -> X {
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
a
}
}
diff --git a/gcc/testsuite/rust/compile/torture/generics30.rs b/gcc/testsuite/rust/compile/torture/generics30.rs
index 24ae58f..a84f140 100644
--- a/gcc/testsuite/rust/compile/torture/generics30.rs
+++ b/gcc/testsuite/rust/compile/torture/generics30.rs
@@ -5,7 +5,6 @@ struct Foo<A, B>(A, B);
impl<T> Foo<T, f32> {
fn test<X>(self, a: X) -> X {
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
a
}
}
diff --git a/gcc/testsuite/rust/compile/torture/traits3.rs b/gcc/testsuite/rust/compile/torture/traits3.rs
index d805da5..dad6dda 100644
--- a/gcc/testsuite/rust/compile/torture/traits3.rs
+++ b/gcc/testsuite/rust/compile/torture/traits3.rs
@@ -10,7 +10,6 @@ struct Baz;
impl Foo for Baz {
fn Bar(self) -> i32 {
- // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
123
}
}
diff --git a/gcc/testsuite/rust/compile/torture/traits7.rs b/gcc/testsuite/rust/compile/torture/traits7.rs
index 8e4472d..545fd39 100644
--- a/gcc/testsuite/rust/compile/torture/traits7.rs
+++ b/gcc/testsuite/rust/compile/torture/traits7.rs
@@ -13,7 +13,6 @@ impl Foo for Bar {
// { dg-warning "unused name" "" { target *-*-* } .-1 }
fn test(self) {}
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
}
fn main() {
diff --git a/gcc/testsuite/rust/compile/torture/unended-raw-byte-string.rs b/gcc/testsuite/rust/compile/torture/unended-raw-byte-string.rs
new file mode 100644
index 0000000..91a3c9a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/unended-raw-byte-string.rs
@@ -0,0 +1,6 @@
+// { dg-excess-errors "...." }
+fn main() {
+ // { dg-error "unended raw byte string literal" "" { target *-*-* } .+1 }
+ let s = br##"123"#
+}
+
diff --git a/gcc/testsuite/rust/compile/traits9.rs b/gcc/testsuite/rust/compile/traits9.rs
index bb3034d..f4308e8 100644
--- a/gcc/testsuite/rust/compile/traits9.rs
+++ b/gcc/testsuite/rust/compile/traits9.rs
@@ -11,6 +11,5 @@ fn main() {
a = Foo(123);
let b: &dyn Bar = &a;
- // { dg-error "bounds not satisfied for Foo .Bar. is not satisfied" "" { target *-*-* } .-1 }
- // { dg-error "expected" "" { target *-*-* } .-2 }
+ // { dg-error "bounds not satisfied for Foo .Bar. is not satisfied .E0277." "" { target *-*-* } .-1 }
}
diff --git a/gcc/testsuite/rust/compile/try_block1.rs b/gcc/testsuite/rust/compile/try_block1.rs
new file mode 100644
index 0000000..7ae0536
--- /dev/null
+++ b/gcc/testsuite/rust/compile/try_block1.rs
@@ -0,0 +1,89 @@
+// { dg-additional-options "-frust-edition=2018" }
+
+#[lang = "sized"]
+trait Sized {}
+
+enum Result<T, E> {
+ Ok(T),
+ Err(E)
+}
+
+pub trait Try {
+ /// The type of this value when viewed as successful.
+ #[unstable(feature = "try_trait", issue = "42327")]
+ type Ok;
+ /// The type of this value when viewed as failed.
+ #[unstable(feature = "try_trait", issue = "42327")]
+ type Error;
+
+ /// Applies the "?" operator. A return of `Ok(t)` means that the
+ /// execution should continue normally, and the result of `?` is the
+ /// value `t`. A return of `Err(e)` means that execution should branch
+ /// to the innermost enclosing `catch`, or return from the function.
+ ///
+ /// If an `Err(e)` result is returned, the value `e` will be "wrapped"
+ /// in the return type of the enclosing scope (which must itself implement
+ /// `Try`). Specifically, the value `X::from_error(From::from(e))`
+ /// is returned, where `X` is the return type of the enclosing function.
+ #[lang = "into_result"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn into_result(self) -> Result<Self::Ok, Self::Error>;
+
+ /// Wrap an error value to construct the composite result. For example,
+ /// `Result::Err(x)` and `Result::from_error(x)` are equivalent.
+ #[lang = "from_error"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn from_error(v: Self::Error) -> Self;
+
+ /// Wrap an OK value to construct the composite result. For example,
+ /// `Result::Ok(x)` and `Result::from_ok(x)` are equivalent.
+ #[lang = "from_ok"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn from_ok(v: Self::Ok) -> Self;
+}
+
+pub struct NoneError;
+
+
+pub enum Option<T> {
+ /// No value
+ None,
+ /// Some value `T`
+ Some(T),
+}
+
+impl<T> Option<T> {
+ pub fn ok_or<E>(self, err: E) -> Result<T, E> {
+ match self {
+ Some(ok) => Result::Ok(ok),
+ None => Result::Err(err)
+ }
+ }
+}
+
+use Option::*;
+
+#[unstable(feature = "try_trait", issue = "42327")]
+impl<T> Try for Option<T> {
+ type Ok = T;
+ type Error = NoneError;
+
+ #[inline]
+ fn into_result(self) -> Result<T, NoneError> {
+ self.ok_or(NoneError)
+ }
+
+ #[inline]
+ fn from_ok(v: T) -> Self {
+ Some(v)
+ }
+
+ #[inline]
+ fn from_error(_: NoneError) -> Self {
+ None
+ }
+}
+
+fn main() {
+ let _: Option<i32> = try { 15i32 };
+}
diff --git a/gcc/testsuite/rust/compile/tuple_mismatch.rs b/gcc/testsuite/rust/compile/tuple_mismatch.rs
index 828586b..1ff358b 100644
--- a/gcc/testsuite/rust/compile/tuple_mismatch.rs
+++ b/gcc/testsuite/rust/compile/tuple_mismatch.rs
@@ -3,6 +3,7 @@ fn main() {
let (_,) = (1, 2); // { dg-error "expected a tuple with 2 elements, found one with 1 element" }
let (_, _) = (1, 2, 3); // { dg-error "expected a tuple with 3 elements, found one with 2 elements" }
let (_, _) = (1,); // { dg-error "expected a tuple with 1 element, found one with 2 elements" }
+ let (_, .., _) = (1,); // { dg-error "expected a tuple with 1 element, found one with 2 elements" }
}
// The lhs and rhs sizes don't match, but we still resolve 'a' to be bool, we don't
diff --git a/gcc/testsuite/rust/compile/unify-errors1.rs b/gcc/testsuite/rust/compile/unify-errors1.rs
new file mode 100644
index 0000000..0fe95ef
--- /dev/null
+++ b/gcc/testsuite/rust/compile/unify-errors1.rs
@@ -0,0 +1,49 @@
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+trait Copy {}
+
+trait MyTrait {}
+
+struct Wrapper<T: MyTrait> {
+ value: T,
+}
+
+struct NotImpl;
+
+trait A {}
+trait B {}
+
+struct Wrapper2<T: A + B> {
+ value: T,
+}
+
+struct NotImpl2;
+
+impl A for NotImpl2 {}
+
+fn takes_tuple(x: (i32, bool)) {}
+
+fn requires_copy<T: Copy>(value: T) {}
+
+pub fn test() {
+ takes_tuple((1, 2));
+ // { dg-error "mismatched types, expected .bool. but got .<integer>. .E0308." "" { target *-*-* } .-1 }
+
+ takes_tuple((1, 2, 3));
+ // { dg-error "mismatched types, expected ..i32, bool.. but got ..<integer>, <integer>, <integer>.. .E0308." "" { target *-*-* } .-1 }
+
+ takes_tuple("hello");
+ // { dg-error "mismatched types, expected ..i32, bool.. but got .& str. .E0308." "" { target *-*-* } .-1 }
+
+ let x = &mut 5;
+ requires_copy(x);
+ // { dg-error "bounds not satisfied for &mut <integer> .Copy. is not satisfied .E0277." "" { target *-*-* } .-1 }
+
+ let _x = Wrapper { value: NotImpl };
+ // { dg-error "bounds not satisfied for NotImpl .MyTrait. is not satisfied .E0277." "" { target *-*-* } .-1 }
+
+ let _x = Wrapper2 { value: NotImpl2 };
+ // { dg-error "bounds not satisfied for NotImpl2 .B. is not satisfied .E0277." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/use_1.rs b/gcc/testsuite/rust/compile/use_1.rs
index e8e2037..21ee3e1 100644
--- a/gcc/testsuite/rust/compile/use_1.rs
+++ b/gcc/testsuite/rust/compile/use_1.rs
@@ -1,4 +1,3 @@
-// { dg-additional-options "-frust-name-resolution-2.0" }
mod frob {}
use foo::bar::baz; // { dg-error "unresolved import .foo::bar::baz." }
diff --git a/gcc/testsuite/rust/compile/usize1.rs b/gcc/testsuite/rust/compile/usize1.rs
index 36cb99b..08f6c9c 100644
--- a/gcc/testsuite/rust/compile/usize1.rs
+++ b/gcc/testsuite/rust/compile/usize1.rs
@@ -1,5 +1,5 @@
fn main() {
let a = [1, 2, 3];
let b: u32 = 1;
- let c = a[b]; // { dg-error "the type ...integer..CAPACITY.. cannot be indexed by .u32." }
+ let c = a[b]; // { dg-error "the type ...integer.; 3.. cannot be indexed by .u32." }
}
diff --git a/gcc/testsuite/rust/compile/while_let1.rs b/gcc/testsuite/rust/compile/while_let1.rs
new file mode 100644
index 0000000..a3fa305
--- /dev/null
+++ b/gcc/testsuite/rust/compile/while_let1.rs
@@ -0,0 +1,109 @@
+// use self::Ordering::*;
+// use Ordering::*;
+
+// enum Ordering {
+// A,
+// B,
+// }
+
+// fn foo(_: Ordering) {}
+
+// fn main() {
+// let a = A;
+
+// foo(a);
+// foo(B);
+// }
+
+#[lang = "sized"]
+trait Sized {}
+
+enum Result<T, E> {
+ Ok(T),
+ Err(E),
+}
+
+pub trait Try {
+ /// The type of this value when viewed as successful.
+ #[unstable(feature = "try_trait", issue = "42327")]
+ type Ok;
+ /// The type of this value when viewed as failed.
+ #[unstable(feature = "try_trait", issue = "42327")]
+ type Error;
+
+ /// Applies the "?" operator. A return of `Ok(t)` means that the
+ /// execution should continue normally, and the result of `?` is the
+ /// value `t`. A return of `Err(e)` means that execution should branch
+ /// to the innermost enclosing `catch`, or return from the function.
+ ///
+ /// If an `Err(e)` result is returned, the value `e` will be "wrapped"
+ /// in the return type of the enclosing scope (which must itself implement
+ /// `Try`). Specifically, the value `X::from_error(From::from(e))`
+ /// is returned, where `X` is the return type of the enclosing function.
+ #[lang = "into_result"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn into_result(self) -> Result<Self::Ok, Self::Error>;
+
+ /// Wrap an error value to construct the composite result. For example,
+ /// `Result::Err(x)` and `Result::from_error(x)` are equivalent.
+ #[lang = "from_error"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn from_error(v: Self::Error) -> Self;
+
+ /// Wrap an OK value to construct the composite result. For example,
+ /// `Result::Ok(x)` and `Result::from_ok(x)` are equivalent.
+ #[lang = "from_ok"]
+ #[unstable(feature = "try_trait", issue = "42327")]
+ fn from_ok(v: Self::Ok) -> Self;
+}
+
+pub struct NoneError;
+
+pub enum Option<T> {
+ /// No value
+ None,
+ /// Some value `T`
+ Some(T),
+}
+
+impl<T> Option<T> {
+ pub fn ok_or<E>(self, err: E) -> Result<T, E> {
+ match self {
+ Some(ok) => Result::Ok(ok),
+ None => Result::Err(err),
+ }
+ }
+}
+
+use Option::*;
+
+#[unstable(feature = "try_trait", issue = "42327")]
+impl<T> Try for Option<T> {
+ type Ok = T;
+ type Error = NoneError;
+
+ #[inline]
+ fn into_result(self) -> Result<T, NoneError> {
+ self.ok_or(NoneError)
+ }
+
+ #[inline]
+ fn from_ok(v: T) -> Self {
+ Some(v)
+ }
+
+ #[inline]
+ fn from_error(_: NoneError) -> Self {
+ None
+ }
+}
+
+fn foo() -> Option<i32> {
+ Option::Some(15)
+}
+
+fn main() {
+ // let _: Option<i32> = try { 15i32 };
+
+ while let Option::Some(15) = foo() {}
+}
diff --git a/gcc/testsuite/rust/compile/while_let_without_label.rs b/gcc/testsuite/rust/compile/while_let_without_label.rs
new file mode 100644
index 0000000..e04e4b5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/while_let_without_label.rs
@@ -0,0 +1,11 @@
+// { dg-additional-options "-frust-compile-until=lowering" }
+
+enum Foo {
+ A(i32),
+}
+
+fn main() {
+ let b = Foo::A(15);
+
+ while let Foo::A(x) = b {}
+}
diff --git a/gcc/testsuite/rust/compile/xfail/name_resolution21.rs b/gcc/testsuite/rust/compile/xfail/name_resolution21.rs
index df48d00..fc8e94b 100644
--- a/gcc/testsuite/rust/compile/xfail/name_resolution21.rs
+++ b/gcc/testsuite/rust/compile/xfail/name_resolution21.rs
@@ -1,5 +1,3 @@
-// { dg-additional-options "-frust-name-resolution-2.0" }
-
pub mod foo {
pub macro bar() {}
}
diff --git a/gcc/testsuite/rust/execute/black_box.rs b/gcc/testsuite/rust/execute/black_box.rs
index 7a9920e..58d10a3 100644
--- a/gcc/testsuite/rust/execute/black_box.rs
+++ b/gcc/testsuite/rust/execute/black_box.rs
@@ -21,10 +21,11 @@ pub fn black_box<T>(mut dummy: T) -> T {
dummy
}
-fn main() {
+fn main() -> i32 {
let dummy: i32 = 42;
let result = black_box(dummy);
unsafe {
printf("Value is: %i\n\0" as *const str as *const i8, result);
}
+ 0
}
diff --git a/gcc/testsuite/rust/execute/execute.exp b/gcc/testsuite/rust/execute/execute.exp
new file mode 100644
index 0000000..3754778
--- /dev/null
+++ b/gcc/testsuite/rust/execute/execute.exp
@@ -0,0 +1,33 @@
+# Copyright (C) 2021-2025 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# Execute tests.
+
+# Load support procs.
+load_lib rust-dg.exp
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+set saved-dg-do-what-default ${dg-do-what-default}
+
+set dg-do-what-default "run"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.rs]] "" ""
+set dg-do-what-default ${saved-dg-do-what-default}
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/rust/execute/inline_asm_inout_ident.rs b/gcc/testsuite/rust/execute/inline_asm_inout_ident.rs
new file mode 100644
index 0000000..b0a3d25
--- /dev/null
+++ b/gcc/testsuite/rust/execute/inline_asm_inout_ident.rs
@@ -0,0 +1,23 @@
+/* { dg-output "Value is: 5\r*\n" } */
+#![feature(rustc_attrs)]
+
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+ () => {};
+}
+
+fn main() -> i32 {
+ let x: i32;
+ // `inout` can also move values to different places
+ unsafe {
+ asm!("inc {}", inout(reg) 4u64=>x);
+ }
+ unsafe {
+ printf("Value is: %i\n\0" as *const str as *const i8, x);
+ }
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/inline_asm_inout_var.rs b/gcc/testsuite/rust/execute/inline_asm_inout_var.rs
new file mode 100644
index 0000000..ff101b8
--- /dev/null
+++ b/gcc/testsuite/rust/execute/inline_asm_inout_var.rs
@@ -0,0 +1,24 @@
+/* { dg-output "Value is: 5\r*\n" } */
+#![feature(rustc_attrs)]
+
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+ () => {};
+}
+
+fn main() -> i32 {
+ let y: i32 = 4;
+ let x: i32;
+ // `inout` can also move values to different places
+ unsafe {
+ asm!("inc {}", inout(reg) y=>x);
+ }
+ unsafe {
+ printf("Value is: %i\n\0" as *const str as *const i8, x);
+ }
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/basic_partial_ord1.rs b/gcc/testsuite/rust/execute/torture/basic_partial_ord1.rs
new file mode 100644
index 0000000..0431629
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/basic_partial_ord1.rs
@@ -0,0 +1,189 @@
+/* { 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)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+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
+}
diff --git a/gcc/testsuite/rust/execute/torture/basic_partial_ord2.rs b/gcc/testsuite/rust/execute/torture/basic_partial_ord2.rs
new file mode 100644
index 0000000..b6a9695
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/basic_partial_ord2.rs
@@ -0,0 +1,197 @@
+/* { 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)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+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
+}
diff --git a/gcc/testsuite/rust/execute/torture/builtin_abort.rs b/gcc/testsuite/rust/execute/torture/builtin_abort.rs
index 9f2d8c2..8c8259a 100644
--- a/gcc/testsuite/rust/execute/torture/builtin_abort.rs
+++ b/gcc/testsuite/rust/execute/torture/builtin_abort.rs
@@ -9,6 +9,6 @@ mod intrinsics {
}
pub fn main () -> i32 {
- abort();
+ intrinsics::abort();
0
}
diff --git a/gcc/testsuite/rust/execute/torture/const-generics-1.rs b/gcc/testsuite/rust/execute/torture/const-generics-1.rs
new file mode 100644
index 0000000..dbb7afe
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/const-generics-1.rs
@@ -0,0 +1,24 @@
+#[lang = "sized"]
+trait Sized {}
+
+struct Foo<const N: usize>;
+
+impl Foo<1> {
+ fn call(&self) -> i32 {
+ 10
+ }
+}
+
+impl Foo<2> {
+ fn call(&self) -> i32 {
+ 20
+ }
+}
+
+fn main() -> i32 {
+ let a = Foo::<1> {};
+ let b = Foo::<2> {};
+ let aa = a.call();
+ let bb = b.call();
+ bb - aa - 10
+}
diff --git a/gcc/testsuite/rust/execute/torture/const_block1.rs b/gcc/testsuite/rust/execute/torture/const_block1.rs
new file mode 100644
index 0000000..eaf3432
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/const_block1.rs
@@ -0,0 +1,9 @@
+const X: i32 = const {
+ let a = 15;
+ let b = 14;
+ a + b
+};
+
+fn main() -> i32 {
+ X - 29
+}
diff --git a/gcc/testsuite/rust/execute/torture/derive-partialeq2.rs b/gcc/testsuite/rust/execute/torture/derive-partialeq2.rs
new file mode 100644
index 0000000..e316017
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/derive-partialeq2.rs
@@ -0,0 +1,80 @@
+// { dg-output "true\r*\nfalse\r*\nfalse\r*\nfalse\r*\nfalse\r*\n" }
+
+#![feature(intrinsics)]
+
+pub mod core {
+ pub mod intrinsics {
+ #[lang = "discriminant_kind"]
+ pub trait DiscriminantKind {
+ #[lang = "discriminant_type"]
+ type Discriminant;
+ }
+
+ extern "rust-intrinsic" {
+ pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+ }
+ }
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+trait Copy {}
+
+#[lang = "structural_peq"]
+trait StructuralPartialEq {}
+
+#[lang = "eq"]
+pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ /// This method tests for `!=`.
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+}
+
+#[derive(PartialEq)]
+enum Foo {
+ A { a: i32, b: i32 },
+ B(i32, i32),
+ C,
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(b: bool) {
+ if b {
+ unsafe { puts("true\0" as *const str as *const i8) }
+ } else {
+ unsafe { puts("false\0" as *const str as *const i8) }
+ }
+}
+
+fn main() -> i32 {
+ let x = Foo::A { a: 15, b: 14 };
+
+ let b1 = x == Foo::A { a: 15, b: 14 };
+ let b12 = x == Foo::A { a: 15, b: 19 };
+ let b13 = x == Foo::A { a: 19, b: 14 };
+ let b2 = x == Foo::B(15, 14);
+ let b3 = x == Foo::C;
+
+ print(b1);
+ print(b12);
+ print(b13);
+ print(b2);
+ print(b3);
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/for-loop1.rs b/gcc/testsuite/rust/execute/torture/for-loop1.rs
index 5a6a70c..3342189 100644
--- a/gcc/testsuite/rust/execute/torture/for-loop1.rs
+++ b/gcc/testsuite/rust/execute/torture/for-loop1.rs
@@ -102,30 +102,30 @@ mod ptr {
#[lang = "const_ptr"]
impl<T> *const T {
pub unsafe fn offset(self, count: isize) -> *const T {
- intrinsics::offset(self, count)
+ crate::intrinsics::offset(self, count)
}
}
#[lang = "mut_ptr"]
impl<T> *mut T {
pub unsafe fn offset(self, count: isize) -> *mut T {
- intrinsics::offset(self, count) as *mut T
+ crate::intrinsics::offset(self, count) as *mut T
}
}
pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
let x = x as *mut u8;
let y = y as *mut u8;
- let len = mem::size_of::<T>() * count;
+ let len = crate::mem::size_of::<T>() * count;
swap_nonoverlapping_bytes(x, y, len)
}
pub unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
// For types smaller than the block optimization below,
// just swap directly to avoid pessimizing codegen.
- if mem::size_of::<T>() < 32 {
+ if crate::mem::size_of::<T>() < 32 {
let z = read(x);
- intrinsics::copy_nonoverlapping(y, x, 1);
+ crate::intrinsics::copy_nonoverlapping(y, x, 1);
write(y, z);
} else {
swap_nonoverlapping(x, y, 1);
@@ -133,12 +133,12 @@ mod ptr {
}
pub unsafe fn write<T>(dst: *mut T, src: T) {
- intrinsics::move_val_init(&mut *dst, src)
+ crate::intrinsics::move_val_init(&mut *dst, src)
}
pub unsafe fn read<T>(src: *const T) -> T {
- let mut tmp: T = mem::uninitialized();
- intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
+ let mut tmp: T = crate::mem::uninitialized();
+ crate::intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
tmp
}
@@ -146,7 +146,7 @@ mod ptr {
struct Block(u64, u64, u64, u64);
struct UnalignedBlock(u64, u64, u64, u64);
- let block_size = mem::size_of::<Block>();
+ let block_size = crate::mem::size_of::<Block>();
// Loop through x & y, copying them `Block` at a time
// The optimizer should unroll the loop fully for most types
@@ -155,31 +155,31 @@ mod ptr {
while i + block_size <= len {
// Create some uninitialized memory as scratch space
// Declaring `t` here avoids aligning the stack when this loop is unused
- let mut t: Block = mem::uninitialized();
+ let mut t: Block = crate::mem::uninitialized();
let t = &mut t as *mut _ as *mut u8;
let x = x.offset(i as isize);
let y = y.offset(i as isize);
// Swap a block of bytes of x & y, using t as a temporary buffer
// This should be optimized into efficient SIMD operations where available
- intrinsics::copy_nonoverlapping(x, t, block_size);
- intrinsics::copy_nonoverlapping(y, x, block_size);
- intrinsics::copy_nonoverlapping(t, y, block_size);
+ crate::intrinsics::copy_nonoverlapping(x, t, block_size);
+ crate::intrinsics::copy_nonoverlapping(y, x, block_size);
+ crate::intrinsics::copy_nonoverlapping(t, y, block_size);
i += block_size;
}
if i < len {
// Swap any remaining bytes
- let mut t: UnalignedBlock = mem::uninitialized();
+ let mut t: UnalignedBlock = crate::mem::uninitialized();
let rem = len - i;
let t = &mut t as *mut _ as *mut u8;
let x = x.offset(i as isize);
let y = y.offset(i as isize);
- intrinsics::copy_nonoverlapping(x, t, rem);
- intrinsics::copy_nonoverlapping(y, x, rem);
- intrinsics::copy_nonoverlapping(t, y, rem);
+ crate::intrinsics::copy_nonoverlapping(x, t, rem);
+ crate::intrinsics::copy_nonoverlapping(y, x, rem);
+ crate::intrinsics::copy_nonoverlapping(t, y, rem);
}
}
}
@@ -194,7 +194,7 @@ mod mem {
pub fn swap<T>(x: &mut T, y: &mut T) {
unsafe {
- ptr::swap_nonoverlapping_one(x, y);
+ crate::ptr::swap_nonoverlapping_one(x, y);
}
}
@@ -204,7 +204,7 @@ mod mem {
}
pub unsafe fn uninitialized<T>() -> T {
- intrinsics::uninit()
+ crate::intrinsics::uninit()
}
}
diff --git a/gcc/testsuite/rust/execute/torture/for-loop2.rs b/gcc/testsuite/rust/execute/torture/for-loop2.rs
index 5ba2cd1..4f5dfe1 100644
--- a/gcc/testsuite/rust/execute/torture/for-loop2.rs
+++ b/gcc/testsuite/rust/execute/torture/for-loop2.rs
@@ -101,30 +101,30 @@ mod ptr {
#[lang = "const_ptr"]
impl<T> *const T {
pub unsafe fn offset(self, count: isize) -> *const T {
- intrinsics::offset(self, count)
+ crate::intrinsics::offset(self, count)
}
}
#[lang = "mut_ptr"]
impl<T> *mut T {
pub unsafe fn offset(self, count: isize) -> *mut T {
- intrinsics::offset(self, count) as *mut T
+ crate::intrinsics::offset(self, count) as *mut T
}
}
pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
let x = x as *mut u8;
let y = y as *mut u8;
- let len = mem::size_of::<T>() * count;
+ let len = crate::mem::size_of::<T>() * count;
swap_nonoverlapping_bytes(x, y, len)
}
pub unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
// For types smaller than the block optimization below,
// just swap directly to avoid pessimizing codegen.
- if mem::size_of::<T>() < 32 {
+ if crate::mem::size_of::<T>() < 32 {
let z = read(x);
- intrinsics::copy_nonoverlapping(y, x, 1);
+ crate::intrinsics::copy_nonoverlapping(y, x, 1);
write(y, z);
} else {
swap_nonoverlapping(x, y, 1);
@@ -132,12 +132,12 @@ mod ptr {
}
pub unsafe fn write<T>(dst: *mut T, src: T) {
- intrinsics::move_val_init(&mut *dst, src)
+ crate::intrinsics::move_val_init(&mut *dst, src)
}
pub unsafe fn read<T>(src: *const T) -> T {
- let mut tmp: T = mem::uninitialized();
- intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
+ let mut tmp: T = crate::mem::uninitialized();
+ crate::intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
tmp
}
@@ -145,7 +145,7 @@ mod ptr {
struct Block(u64, u64, u64, u64);
struct UnalignedBlock(u64, u64, u64, u64);
- let block_size = mem::size_of::<Block>();
+ let block_size = crate::mem::size_of::<Block>();
// Loop through x & y, copying them `Block` at a time
// The optimizer should unroll the loop fully for most types
@@ -154,31 +154,31 @@ mod ptr {
while i + block_size <= len {
// Create some uninitialized memory as scratch space
// Declaring `t` here avoids aligning the stack when this loop is unused
- let mut t: Block = mem::uninitialized();
+ let mut t: Block = crate::mem::uninitialized();
let t = &mut t as *mut _ as *mut u8;
let x = x.offset(i as isize);
let y = y.offset(i as isize);
// Swap a block of bytes of x & y, using t as a temporary buffer
// This should be optimized into efficient SIMD operations where available
- intrinsics::copy_nonoverlapping(x, t, block_size);
- intrinsics::copy_nonoverlapping(y, x, block_size);
- intrinsics::copy_nonoverlapping(t, y, block_size);
+ crate::intrinsics::copy_nonoverlapping(x, t, block_size);
+ crate::intrinsics::copy_nonoverlapping(y, x, block_size);
+ crate::intrinsics::copy_nonoverlapping(t, y, block_size);
i += block_size;
}
if i < len {
// Swap any remaining bytes
- let mut t: UnalignedBlock = mem::uninitialized();
+ let mut t: UnalignedBlock = crate::mem::uninitialized();
let rem = len - i;
let t = &mut t as *mut _ as *mut u8;
let x = x.offset(i as isize);
let y = y.offset(i as isize);
- intrinsics::copy_nonoverlapping(x, t, rem);
- intrinsics::copy_nonoverlapping(y, x, rem);
- intrinsics::copy_nonoverlapping(t, y, rem);
+ crate::intrinsics::copy_nonoverlapping(x, t, rem);
+ crate::intrinsics::copy_nonoverlapping(y, x, rem);
+ crate::intrinsics::copy_nonoverlapping(t, y, rem);
}
}
}
@@ -193,7 +193,7 @@ mod mem {
pub fn swap<T>(x: &mut T, y: &mut T) {
unsafe {
- ptr::swap_nonoverlapping_one(x, y);
+ crate::ptr::swap_nonoverlapping_one(x, y);
}
}
@@ -203,7 +203,7 @@ mod mem {
}
pub unsafe fn uninitialized<T>() -> T {
- intrinsics::uninit()
+ crate::intrinsics::uninit()
}
}
diff --git a/gcc/testsuite/rust/execute/torture/impl_desugar-2.rs b/gcc/testsuite/rust/execute/torture/impl_desugar-2.rs
new file mode 100644
index 0000000..c73ea34
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_desugar-2.rs
@@ -0,0 +1,32 @@
+#[lang = "sized"]
+trait Sized {}
+
+macro_rules! impl_foo {
+ () => { impl Foo }
+}
+
+pub trait Foo {}
+
+pub trait Bar {
+ type Baz;
+}
+
+struct MyBaz; // { dg-warning "struct is never constructed" }
+impl Foo for MyBaz {}
+
+struct MyBar;
+
+impl Bar for MyBar {
+ type Baz = MyBaz;
+}
+
+pub fn foo(_value: impl Bar<Baz = impl_foo!()>) -> i32 {
+ 15
+}
+
+fn main() -> i32 {
+ let bar = MyBar;
+ let result: i32 = foo(bar);
+
+ result - 15
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_desugar.rs b/gcc/testsuite/rust/execute/torture/impl_desugar.rs
new file mode 100644
index 0000000..22d3951
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_desugar.rs
@@ -0,0 +1,32 @@
+#[lang = "sized"]
+trait Sized {}
+
+pub trait Foo {}
+
+pub trait Bar {
+ type Baz;
+}
+
+struct MyBaz; // { dg-warning "struct is never constructed" }
+impl Foo for MyBaz {}
+
+struct MyBar;
+
+impl Bar for MyBar {
+ type Baz = MyBaz;
+}
+
+pub fn foo<T, U>(_value: T) -> i32
+where
+ T: Bar<Baz = U>,
+ U: Foo,
+{
+ 15
+}
+
+fn main() -> i32 {
+ let bar = MyBar;
+ let result: i32 = foo::<MyBar, MyBaz>(bar);
+
+ result - 15
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_rpit1.rs b/gcc/testsuite/rust/execute/torture/impl_rpit1.rs
new file mode 100644
index 0000000..8ce5f21
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_rpit1.rs
@@ -0,0 +1,28 @@
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+ fn id(&self) -> i32;
+}
+
+struct Thing(i32);
+
+impl Foo for Thing {
+ fn id(&self) -> i32 {
+ self.0
+ }
+}
+
+fn make_thing(a: i32) -> impl Foo {
+ Thing(a)
+}
+
+fn use_foo(f: impl Foo) -> i32 {
+ f.id()
+}
+
+fn main() -> i32 {
+ let value = make_thing(42);
+ let val = use_foo(value);
+ val - 42
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_rpit2.rs b/gcc/testsuite/rust/execute/torture/impl_rpit2.rs
new file mode 100644
index 0000000..f7cbbb6
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_rpit2.rs
@@ -0,0 +1,36 @@
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+ fn id(&self) -> i32;
+}
+
+struct Thing(i32);
+
+impl Thing {
+ fn double(&self) -> i32 {
+ // { dg-warning "associated function is never used: .double." "" { target *-*-* } .-1 }
+ self.0 * 2
+ }
+}
+
+impl Foo for Thing {
+ fn id(&self) -> i32 {
+ self.0
+ }
+}
+
+fn make_thing(a: i32) -> impl Foo {
+ Thing(a)
+}
+
+fn use_foo(f: impl Foo) -> i32 {
+ f.id()
+}
+
+fn main() -> i32 {
+ let value = make_thing(21);
+ let id = use_foo(value);
+
+ id - 21
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_rpit3.rs b/gcc/testsuite/rust/execute/torture/impl_rpit3.rs
new file mode 100644
index 0000000..dd68eb2
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_rpit3.rs
@@ -0,0 +1,25 @@
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+ fn id(&self) -> i32;
+}
+
+struct Thing(i32);
+
+impl Foo for Thing {
+ fn id(&self) -> i32 {
+ self.0
+ }
+}
+
+fn make_thing() -> impl Foo {
+ Thing(99)
+}
+
+fn main() -> i32 {
+ let v = make_thing();
+ let r = &v;
+ let val = r.id();
+ val - 99
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_trait1.rs b/gcc/testsuite/rust/execute/torture/impl_trait1.rs
new file mode 100644
index 0000000..33a5c8c
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_trait1.rs
@@ -0,0 +1,31 @@
+#[lang = "sized"]
+trait Sized {}
+
+pub trait Value {
+ fn get(&self) -> i32;
+}
+
+struct Foo(i32);
+struct Bar(i32);
+
+impl Value for Foo {
+ fn get(&self) -> i32 {
+ self.0
+ }
+}
+impl Value for Bar {
+ fn get(&self) -> i32 {
+ self.0
+ }
+}
+
+pub fn foo(a: impl Value, b: impl Value) -> i32 {
+ a.get() + b.get()
+}
+
+fn main() -> i32 {
+ let a = Foo(1);
+ let b = Bar(2);
+
+ foo(a, b) - 3
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_trait2.rs b/gcc/testsuite/rust/execute/torture/impl_trait2.rs
new file mode 100644
index 0000000..29f393d
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_trait2.rs
@@ -0,0 +1,31 @@
+#[lang = "sized"]
+trait Sized {}
+
+pub trait Value {
+ fn get(&self) -> i32;
+}
+
+struct Foo(i32);
+struct Bar(i32);
+
+impl Value for Foo {
+ fn get(&self) -> i32 {
+ self.0
+ }
+}
+impl Value for Bar {
+ fn get(&self) -> i32 {
+ self.0
+ }
+}
+
+pub fn foo(a: &impl Value, b: &impl Value) -> i32 {
+ a.get() + b.get()
+}
+
+fn main() -> i32 {
+ let a = Foo(1);
+ let b = Bar(2);
+
+ foo(&a, &b) - 3
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_trait3.rs b/gcc/testsuite/rust/execute/torture/impl_trait3.rs
new file mode 100644
index 0000000..c1cec07
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_trait3.rs
@@ -0,0 +1,45 @@
+/* { dg-output "Hello from Message\r*\n" } */
+#[lang = "sized"]
+pub trait Sized {}
+
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+trait Speak {
+ fn speak(&self) -> &'static str;
+}
+
+trait Printer {
+ fn print(&self, input: impl Speak);
+}
+
+struct Console;
+
+impl Printer for Console {
+ fn print(&self, input: impl Speak) {
+ unsafe {
+ let a = input.speak();
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c);
+ }
+ }
+}
+
+struct Message(&'static str);
+
+impl Speak for Message {
+ fn speak(&self) -> &'static str {
+ self.0
+ }
+}
+
+fn main() -> i32 {
+ let c = Console;
+ let msg = Message("Hello from Message\n");
+ c.print(msg);
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/impl_trait4.rs b/gcc/testsuite/rust/execute/torture/impl_trait4.rs
new file mode 100644
index 0000000..67d0095
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/impl_trait4.rs
@@ -0,0 +1,31 @@
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+ fn id(&self) -> i32;
+}
+
+struct A(i32);
+struct B(i32);
+
+impl Foo for A {
+ fn id(&self) -> i32 {
+ self.0
+ }
+}
+
+impl Foo for B {
+ fn id(&self) -> i32 {
+ self.0
+ }
+}
+
+fn takes_tuple(pair: (impl Foo, impl Foo)) -> i32 {
+ pair.0.id() + pair.1.id()
+}
+
+fn main() -> i32 {
+ let a = A(1);
+ let b = B(2);
+ takes_tuple((a, b)) - 3
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1481.rs b/gcc/testsuite/rust/execute/torture/issue-1481.rs
new file mode 100644
index 0000000..2ff78d9
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-1481.rs
@@ -0,0 +1,35 @@
+/* { dg-output "called Foo::print\\(\\)\r*" } */
+/* { dg-options "-w" } */
+
+#[lang = "sized"]
+trait Sized {}
+
+trait Printable {
+ fn print(&self);
+}
+
+struct Foo;
+
+impl Printable for Foo {
+ fn print(&self) {
+ // Simulate output
+ unsafe {
+ puts("called Foo::print()\0" as *const _ as *const i8);
+ }
+ }
+}
+
+fn get_printable() -> impl Printable {
+ Foo
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn main() -> i32 {
+ let p = get_printable();
+ p.print();
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1482.rs b/gcc/testsuite/rust/execute/torture/issue-1482.rs
new file mode 100644
index 0000000..ed8dc81
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-1482.rs
@@ -0,0 +1,23 @@
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+ #[lang = "fn_once_output"]
+ type Output;
+
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+fn takes_fn(a: i32, f: impl FnOnce(i32) -> i32) -> i32 {
+ f(a)
+}
+
+pub fn main() -> i32 {
+ let capture = 2;
+ let a = |i: i32| {
+ let b = i + capture;
+ b
+ };
+ takes_fn(1, a) - 3
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-2005.rs b/gcc/testsuite/rust/execute/torture/issue-2005.rs
new file mode 100644
index 0000000..87edb95
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-2005.rs
@@ -0,0 +1,465 @@
+// { dg-additional-options "-w" }
+/* { dg-output "WORKS\r?\n" } */
+#![feature(intrinsics)]
+
+mod core {
+ mod option {
+ // #[rustc_diagnostic_item = "option_type"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Option<T> {
+ /// No value
+ #[lang = "None"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ None,
+ /// Some value `T`
+ #[lang = "Some"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+ }
+ }
+
+ mod marker {
+ #[lang = "phantom_data"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`")]
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {
+ // Empty.
+ }
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(Eq)]`")]
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {
+ // Empty.
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[lang = "sized"]
+ // #[rustc_on_unimplemented(
+ // message = "the size for values of type `{Self}` cannot be known at compilation time",
+ // label = "doesn't have a size known at compile-time"
+ // )]
+ // #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
+ // #[rustc_specialization_trait]
+ pub trait Sized {
+ // Empty.
+ }
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ // #[derive(Clone, Copy, PartialEq, Debug, Hash)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Ordering {
+ /// An ordering where a compared value is less than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Less = -1,
+ /// An ordering where a compared value is equal to another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Equal = 0,
+ /// An ordering where a compared value is greater than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} == {Rhs}`"
+ // )]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Eq: PartialEq<Self> {
+ // this method is used solely by #[deriving] to assert
+ // that every component of a type implements #[deriving]
+ // itself, the current deriving infrastructure means doing this
+ // assertion without using a method on this trait is nearly
+ // impossible.
+ //
+ // This should never be implemented by hand.
+ #[doc(hidden)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+
+ #[lang = "partial_ord"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`"
+ // )]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ /// This method returns an ordering between `self` and `other` values if one exists.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// let result = 1.0.partial_cmp(&2.0);
+ /// assert_eq!(result, Some(Ordering::Less));
+ ///
+ /// let result = 1.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Equal));
+ ///
+ /// let result = 2.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Greater));
+ /// ```
+ ///
+ /// When comparison is impossible:
+ ///
+ /// ```
+ /// let result = f64::NAN.partial_cmp(&1.0);
+ /// assert_eq!(result, None);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+ /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 < 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 < 1.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn lt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 <= 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 <= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn le(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 > 2.0;
+ /// assert_eq!(result, false);
+ ///
+ /// let result = 2.0 > 2.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn gt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 2.0 >= 1.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 >= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ge(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+ }
+
+ #[doc(alias = "<")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Ord: Eq + PartialOrd<Self> {
+ /// This method returns an [`Ordering`] between `self` and `other`.
+ ///
+ /// By convention, `self.cmp(&other)` returns the ordering matching the expression
+ /// `self <operator> other` if true.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// assert_eq!(5.cmp(&10), Ordering::Less);
+ /// assert_eq!(10.cmp(&5), Ordering::Greater);
+ /// assert_eq!(5.cmp(&5), Ordering::Equal);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn cmp(&self, other: &Self) -> Ordering;
+
+ /// Compares and returns the maximum of two values.
+ ///
+ /// Returns the second argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(2, 1.max(2));
+ /// assert_eq!(2, 2.max(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn max(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Compares and returns the minimum of two values.
+ ///
+ /// Returns the first argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(1, 1.min(2));
+ /// assert_eq!(2, 2.min(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn min(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Restrict a value to a certain interval.
+ ///
+ /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
+ /// less than `min`. Otherwise this returns `self`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `min > max`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(clamp)]
+ ///
+ /// assert!((-3).clamp(-2, 1) == -2);
+ /// assert!(0.clamp(-2, 1) == 0);
+ /// assert!(2.clamp(-2, 1) == 1);
+ /// ```
+ #[must_use]
+ #[unstable(feature = "clamp", issue = "44095")]
+ fn clamp(self, min: Self, max: Self) -> Self
+ where
+ Self: Sized,
+ {
+ if self < min {
+ min
+ } else if self > max {
+ max
+ } else {
+ self
+ }
+ }
+ }
+ }
+
+ pub mod intrinsics {
+ #[lang = "discriminant_kind"]
+ pub trait DiscriminantKind {
+ #[lang = "discriminant_type"]
+ type Discriminant;
+ }
+
+ extern "rust-intrinsic" {
+ pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+ }
+ }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+// --------------
+
+impl PartialEq for isize {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+impl PartialOrd for isize {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl Eq for isize {}
+
+impl Ord for isize {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self > *other {
+ Ordering::Greater
+ } else if *self < *other {
+ Ordering::Less
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+// ----------------------------------
+
+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::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl Ord for i32 {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self > *other {
+ Ordering::Greater
+ } else if *self < *other {
+ Ordering::Less
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+impl Eq for i32 {}
+
+#[derive(Ord, PartialOrd, PartialEq, Eq)]
+enum Foo {
+ A,
+ B(i32),
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ let a = Foo::A;
+ let b = Foo::B(15);
+
+ if (a != b) {
+ print("WORKS");
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/issue-3836.rs b/gcc/testsuite/rust/execute/torture/issue-3836.rs
new file mode 100644
index 0000000..61ad424
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-3836.rs
@@ -0,0 +1,454 @@
+// { dg-options "-w" }
+// { dg-output "less\r*\n" }
+
+#![feature(intrinsics)]
+
+mod core {
+ mod option {
+ // #[rustc_diagnostic_item = "option_type"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Option<T> {
+ /// No value
+ #[lang = "None"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ None,
+ /// Some value `T`
+ #[lang = "Some"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+ }
+ }
+
+ mod marker {
+ #[lang = "phantom_data"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`")]
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {
+ // Empty.
+ }
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(Eq)]`")]
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {
+ // Empty.
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[lang = "sized"]
+ // #[rustc_on_unimplemented(
+ // message = "the size for values of type `{Self}` cannot be known at compilation time",
+ // label = "doesn't have a size known at compile-time"
+ // )]
+ // #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
+ // #[rustc_specialization_trait]
+ pub trait Sized {
+ // Empty.
+ }
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ // #[derive(Clone, Copy, PartialEq, Debug, Hash)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Ordering {
+ /// An ordering where a compared value is less than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Less = -1,
+ /// An ordering where a compared value is equal to another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Equal = 0,
+ /// An ordering where a compared value is greater than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} == {Rhs}`"
+ // )]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Eq: PartialEq<Self> {
+ // this method is used solely by #[deriving] to assert
+ // that every component of a type implements #[deriving]
+ // itself, the current deriving infrastructure means doing this
+ // assertion without using a method on this trait is nearly
+ // impossible.
+ //
+ // This should never be implemented by hand.
+ #[doc(hidden)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+
+ #[lang = "partial_ord"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`"
+ // )]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ /// This method returns an ordering between `self` and `other` values if one exists.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// let result = 1.0.partial_cmp(&2.0);
+ /// assert_eq!(result, Some(Ordering::Less));
+ ///
+ /// let result = 1.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Equal));
+ ///
+ /// let result = 2.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Greater));
+ /// ```
+ ///
+ /// When comparison is impossible:
+ ///
+ /// ```
+ /// let result = f64::NAN.partial_cmp(&1.0);
+ /// assert_eq!(result, None);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+ /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 < 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 < 1.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn lt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 <= 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 <= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn le(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 > 2.0;
+ /// assert_eq!(result, false);
+ ///
+ /// let result = 2.0 > 2.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn gt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 2.0 >= 1.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 >= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ge(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+ }
+
+ #[doc(alias = "<")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Ord: Eq + PartialOrd<Self> {
+ /// This method returns an [`Ordering`] between `self` and `other`.
+ ///
+ /// By convention, `self.cmp(&other)` returns the ordering matching the expression
+ /// `self <operator> other` if true.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// assert_eq!(5.cmp(&10), Ordering::Less);
+ /// assert_eq!(10.cmp(&5), Ordering::Greater);
+ /// assert_eq!(5.cmp(&5), Ordering::Equal);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn cmp(&self, other: &Self) -> Ordering;
+
+ /// Compares and returns the maximum of two values.
+ ///
+ /// Returns the second argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(2, 1.max(2));
+ /// assert_eq!(2, 2.max(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn max(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Compares and returns the minimum of two values.
+ ///
+ /// Returns the first argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(1, 1.min(2));
+ /// assert_eq!(2, 2.min(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn min(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Restrict a value to a certain interval.
+ ///
+ /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
+ /// less than `min`. Otherwise this returns `self`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `min > max`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(clamp)]
+ ///
+ /// assert!((-3).clamp(-2, 1) == -2);
+ /// assert!(0.clamp(-2, 1) == 0);
+ /// assert!(2.clamp(-2, 1) == 1);
+ /// ```
+ #[must_use]
+ #[unstable(feature = "clamp", issue = "44095")]
+ fn clamp(self, min: Self, max: Self) -> Self
+ where
+ Self: Sized,
+ {
+ if self < min {
+ min
+ } else if self > max {
+ max
+ } else {
+ self
+ }
+ }
+ }
+ }
+
+ pub mod intrinsics {
+ #[lang = "discriminant_kind"]
+ pub trait DiscriminantKind {
+ #[lang = "discriminant_type"]
+ type Discriminant;
+ }
+
+ extern "rust-intrinsic" {
+ pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+ }
+ }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+// for comparing discriminant_value
+impl PartialEq for isize {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+// for comparing discriminant_value
+impl PartialOrd for isize {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+impl Eq for i32 {}
+
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl Ord for i32 {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self > *other {
+ Ordering::Greater
+ } else if *self < *other {
+ Ordering::Less
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+// ------------
+
+#[derive(Ord, PartialOrd, PartialEq, Eq)]
+struct Bar {
+ a: i32,
+ b: i32,
+}
+
+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
+}
diff --git a/gcc/testsuite/rust/execute/torture/iter1.rs b/gcc/testsuite/rust/execute/torture/iter1.rs
index c3b6c7b..233eb60 100644
--- a/gcc/testsuite/rust/execute/torture/iter1.rs
+++ b/gcc/testsuite/rust/execute/torture/iter1.rs
@@ -99,30 +99,30 @@ mod ptr {
#[lang = "const_ptr"]
impl<T> *const T {
pub unsafe fn offset(self, count: isize) -> *const T {
- intrinsics::offset(self, count)
+ crate::intrinsics::offset(self, count)
}
}
#[lang = "mut_ptr"]
impl<T> *mut T {
pub unsafe fn offset(self, count: isize) -> *mut T {
- intrinsics::offset(self, count) as *mut T
+ crate::intrinsics::offset(self, count) as *mut T
}
}
pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
let x = x as *mut u8;
let y = y as *mut u8;
- let len = mem::size_of::<T>() * count;
+ let len = crate::mem::size_of::<T>() * count;
swap_nonoverlapping_bytes(x, y, len)
}
pub unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
// For types smaller than the block optimization below,
// just swap directly to avoid pessimizing codegen.
- if mem::size_of::<T>() < 32 {
+ if crate::mem::size_of::<T>() < 32 {
let z = read(x);
- intrinsics::copy_nonoverlapping(y, x, 1);
+ crate::intrinsics::copy_nonoverlapping(y, x, 1);
write(y, z);
} else {
swap_nonoverlapping(x, y, 1);
@@ -130,12 +130,12 @@ mod ptr {
}
pub unsafe fn write<T>(dst: *mut T, src: T) {
- intrinsics::move_val_init(&mut *dst, src)
+ crate::intrinsics::move_val_init(&mut *dst, src)
}
pub unsafe fn read<T>(src: *const T) -> T {
- let mut tmp: T = mem::uninitialized();
- intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
+ let mut tmp: T = crate::mem::uninitialized();
+ crate::intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
tmp
}
@@ -143,7 +143,7 @@ mod ptr {
struct Block(u64, u64, u64, u64);
struct UnalignedBlock(u64, u64, u64, u64);
- let block_size = mem::size_of::<Block>();
+ let block_size = crate::mem::size_of::<Block>();
// Loop through x & y, copying them `Block` at a time
// The optimizer should unroll the loop fully for most types
@@ -152,31 +152,31 @@ mod ptr {
while i + block_size <= len {
// Create some uninitialized memory as scratch space
// Declaring `t` here avoids aligning the stack when this loop is unused
- let mut t: Block = mem::uninitialized();
+ let mut t: Block = crate::mem::uninitialized();
let t = &mut t as *mut _ as *mut u8;
let x = x.offset(i as isize);
let y = y.offset(i as isize);
// Swap a block of bytes of x & y, using t as a temporary buffer
// This should be optimized into efficient SIMD operations where available
- intrinsics::copy_nonoverlapping(x, t, block_size);
- intrinsics::copy_nonoverlapping(y, x, block_size);
- intrinsics::copy_nonoverlapping(t, y, block_size);
+ crate::intrinsics::copy_nonoverlapping(x, t, block_size);
+ crate::intrinsics::copy_nonoverlapping(y, x, block_size);
+ crate::intrinsics::copy_nonoverlapping(t, y, block_size);
i += block_size;
}
if i < len {
// Swap any remaining bytes
- let mut t: UnalignedBlock = mem::uninitialized();
+ let mut t: UnalignedBlock = crate::mem::uninitialized();
let rem = len - i;
let t = &mut t as *mut _ as *mut u8;
let x = x.offset(i as isize);
let y = y.offset(i as isize);
- intrinsics::copy_nonoverlapping(x, t, rem);
- intrinsics::copy_nonoverlapping(y, x, rem);
- intrinsics::copy_nonoverlapping(t, y, rem);
+ crate::intrinsics::copy_nonoverlapping(x, t, rem);
+ crate::intrinsics::copy_nonoverlapping(y, x, rem);
+ crate::intrinsics::copy_nonoverlapping(t, y, rem);
}
}
}
@@ -191,7 +191,7 @@ mod mem {
pub fn swap<T>(x: &mut T, y: &mut T) {
unsafe {
- ptr::swap_nonoverlapping_one(x, y);
+ crate::ptr::swap_nonoverlapping_one(x, y);
}
}
@@ -201,7 +201,7 @@ mod mem {
}
pub unsafe fn uninitialized<T>() -> T {
- intrinsics::uninit()
+ crate::intrinsics::uninit()
}
}
diff --git a/gcc/testsuite/rust/execute/torture/match-identifierpattern.rs b/gcc/testsuite/rust/execute/torture/match-identifierpattern.rs
new file mode 100644
index 0000000..b102ad1
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match-identifierpattern.rs
@@ -0,0 +1,10 @@
+fn main() -> i32 {
+ let mut x = 2;
+
+ match x {
+ a @ 2 => { x = a + 1 },
+ _ => {}
+ }
+
+ x - 3
+}
diff --git a/gcc/testsuite/rust/execute/torture/match-restpattern-tuple.rs b/gcc/testsuite/rust/execute/torture/match-restpattern-tuple.rs
new file mode 100644
index 0000000..2c1418c
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match-restpattern-tuple.rs
@@ -0,0 +1,27 @@
+// { dg-output "correct\r*" }
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn main() -> i32 {
+ let x = (1, 2, 3, 4);
+ let mut ret = 1;
+
+ match x {
+ (1, .., 2, 4) => {
+ /* should not take this path */
+ unsafe { puts("wrong\0" as *const str as *const i8) }
+ },
+ (2, ..) => {
+ /* should not take this path */
+ unsafe { puts("wrong\0" as *const str as *const i8) }
+ },
+ (b, .., 4) => {
+ ret -= b;
+ unsafe { puts("correct\0" as *const str as *const i8) }
+ },
+ _ => {}
+ }
+
+ ret
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/execute/torture/match-slicepattern-array-1.rs b/gcc/testsuite/rust/execute/torture/match-slicepattern-array-1.rs
new file mode 100644
index 0000000..95c55d8
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match-slicepattern-array-1.rs
@@ -0,0 +1,23 @@
+// { dg-output "correct\r*" }
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn main() -> i32 {
+ let a = [0, 1];
+ let mut ret = 1;
+
+ match a {
+ [0, 0] => {
+ /* should not take this path */
+ unsafe { puts("wrong\0" as *const str as *const i8) }
+ },
+ [0, b] => {
+ ret -= b;
+ unsafe { puts("correct\0" as *const str as *const i8) }
+ },
+ _ => {}
+ }
+
+ ret
+}
diff --git a/gcc/testsuite/rust/execute/torture/match-slicepattern-slice-1.rs b/gcc/testsuite/rust/execute/torture/match-slicepattern-slice-1.rs
new file mode 100644
index 0000000..3ed0b644
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match-slicepattern-slice-1.rs
@@ -0,0 +1,24 @@
+// { dg-output "correct\r*" }
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn main() -> i32 {
+ let arr = [0, 1];
+ let a: &[i32] = &arr;
+ let mut ret = 1;
+
+ match a {
+ [0, 0] => {
+ /* should not take this path */
+ unsafe { puts("wrong\0" as *const str as *const i8) }
+ },
+ [0, b] => {
+ ret -= b;
+ unsafe { puts("correct\0" as *const str as *const i8) }
+ },
+ _ => {}
+ }
+
+ ret
+}
diff --git a/gcc/testsuite/rust/execute/torture/match-tuplestructpattern.rs b/gcc/testsuite/rust/execute/torture/match-tuplestructpattern.rs
new file mode 100644
index 0000000..323109c
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match-tuplestructpattern.rs
@@ -0,0 +1,12 @@
+fn main() -> i32 {
+ struct A (i32, i32);
+ let a = A (0, 1);
+ let mut ret = 1;
+
+ match a {
+ A (0, b) => { ret -= b },
+ _ => {}
+ }
+
+ ret
+}
diff --git a/gcc/testsuite/rust/execute/torture/min_specialization2.rs b/gcc/testsuite/rust/execute/torture/min_specialization2.rs
index d3239ee..74faee4 100644
--- a/gcc/testsuite/rust/execute/torture/min_specialization2.rs
+++ b/gcc/testsuite/rust/execute/torture/min_specialization2.rs
@@ -8,7 +8,7 @@ trait Foo {
}
impl<T> Foo for T {
- default fn foo(&self) -> i32 { // { dg-warning "unused" }
+ default fn foo(&self) -> i32 {
15
}
}
diff --git a/gcc/testsuite/rust/execute/torture/name_resolution.rs b/gcc/testsuite/rust/execute/torture/name_resolution.rs
index 7492183..a2eaf48 100644
--- a/gcc/testsuite/rust/execute/torture/name_resolution.rs
+++ b/gcc/testsuite/rust/execute/torture/name_resolution.rs
@@ -1,4 +1,3 @@
-// { dg-additional-options "-frust-name-resolution-2.0" }
// { dg-output "Value is 10\r*\n" }
const BAZ: i32 = 10;
diff --git a/gcc/testsuite/rust/execute/torture/offset_of1.rs b/gcc/testsuite/rust/execute/torture/offset_of1.rs
new file mode 100644
index 0000000..7d39483
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/offset_of1.rs
@@ -0,0 +1,16 @@
+// { dg-do run { target x86_64*-*-* } }
+// { dg-additional-options "-frust-assume-builtin-offset-of" }
+
+pub struct Foo {
+ pub a: i32,
+ pub b: i32,
+}
+
+fn main() -> i32 {
+ let a = offset_of!(Foo, a); // valid
+ let b = offset_of!(Foo, b); // valid
+
+ let res = a + b - 4;
+
+ res as i32
+}
diff --git a/gcc/testsuite/rust/execute/torture/partial-eq-1.rs b/gcc/testsuite/rust/execute/torture/partial-eq-1.rs
new file mode 100644
index 0000000..db123a1
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/partial-eq-1.rs
@@ -0,0 +1,103 @@
+/* { dg-output "a == b\r*\na != c\r*\n" }*/
+/* { dg-options "-w" } */
+
+mod core {
+ mod marker {
+ #[lang = "phantom_data"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {
+ // Empty.
+ }
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {
+ // Empty.
+ }
+
+ #[lang = "sized"]
+ pub trait Sized {}
+ }
+
+ pub mod cmp {
+ use super::marker::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) {}
+ }
+ }
+}
+
+use core::cmp::{Eq, PartialEq};
+
+// PartialEq for i32 and u32 so we can compare across types
+impl PartialEq<u32> for i32 {
+ fn eq(&self, other: &u32) -> bool {
+ *self >= 0 && (*self as u32) == *other
+ }
+}
+impl PartialEq<i32> for u32 {
+ fn eq(&self, other: &i32) -> bool {
+ *other >= 0 && *self == *other as u32
+ }
+}
+
+// Our generic struct
+struct Foo<T> {
+ value: T,
+}
+
+// Manual impl of PartialEq for different generic params
+impl<T, U> PartialEq<Foo<U>> for Foo<T>
+where
+ T: PartialEq<U>,
+{
+ fn eq(&self, other: &Foo<U>) -> bool {
+ self.value.eq(&other.value)
+ }
+}
+
+impl<T: PartialEq> Eq for Foo<T> {}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ let a = Foo { value: 42i32 };
+ let b = Foo { value: 42u32 };
+ let c = Foo { value: 7u32 };
+
+ if a == b {
+ print("a == b");
+ } else {
+ print("a != b");
+ }
+
+ if a == c {
+ print("a == c");
+ } else {
+ print("a != c");
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/partial-eq-2.rs b/gcc/testsuite/rust/execute/torture/partial-eq-2.rs
new file mode 100644
index 0000000..debed8c
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/partial-eq-2.rs
@@ -0,0 +1,60 @@
+/* { dg-output "a == b\r*\na != c\r*\n" }*/
+/* { dg-options "-w" } */
+
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "eq"]
+pub trait PartialEq<Rhs: ?Sized = Self> {
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+}
+
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+struct Foo<T> {
+ value: T,
+}
+
+impl<T: PartialEq> PartialEq for Foo<T> {
+ fn eq(&self, other: &Self) -> bool {
+ self.value.eq(&other.value)
+ }
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ let a = Foo { value: 42i32 };
+ let b = Foo { value: 42i32 };
+ let c = Foo { value: 99i32 };
+
+ if a == b {
+ print("a == b");
+ } else {
+ print("a != b");
+ }
+
+ if a == c {
+ print("a == c");
+ } else {
+ print("a != c");
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/partial-eq-3.rs b/gcc/testsuite/rust/execute/torture/partial-eq-3.rs
new file mode 100644
index 0000000..849910a
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/partial-eq-3.rs
@@ -0,0 +1,457 @@
+/* { dg-output "a == b\r*\na != c\r*\n" }*/
+/* { dg-options "-w" } */
+
+#![feature(intrinsics)]
+
+mod core {
+ mod option {
+ // #[rustc_diagnostic_item = "option_type"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Option<T> {
+ /// No value
+ #[lang = "None"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ None,
+ /// Some value `T`
+ #[lang = "Some"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+ }
+ }
+
+ mod marker {
+ #[lang = "phantom_data"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`")]
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {
+ // Empty.
+ }
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(Eq)]`")]
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {
+ // Empty.
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[lang = "sized"]
+ // #[rustc_on_unimplemented(
+ // message = "the size for values of type `{Self}` cannot be known at compilation time",
+ // label = "doesn't have a size known at compile-time"
+ // )]
+ // #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
+ // #[rustc_specialization_trait]
+ pub trait Sized {
+ // Empty.
+ }
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ // #[derive(Clone, Copy, PartialEq, Debug, Hash)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Ordering {
+ /// An ordering where a compared value is less than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Less = -1,
+ /// An ordering where a compared value is equal to another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Equal = 0,
+ /// An ordering where a compared value is greater than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} == {Rhs}`"
+ // )]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Eq: PartialEq<Self> {
+ // this method is used solely by #[deriving] to assert
+ // that every component of a type implements #[deriving]
+ // itself, the current deriving infrastructure means doing this
+ // assertion without using a method on this trait is nearly
+ // impossible.
+ //
+ // This should never be implemented by hand.
+ #[doc(hidden)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+
+ #[lang = "partial_ord"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`"
+ // )]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ /// This method returns an ordering between `self` and `other` values if one exists.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// let result = 1.0.partial_cmp(&2.0);
+ /// assert_eq!(result, Some(Ordering::Less));
+ ///
+ /// let result = 1.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Equal));
+ ///
+ /// let result = 2.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Greater));
+ /// ```
+ ///
+ /// When comparison is impossible:
+ ///
+ /// ```
+ /// let result = f64::NAN.partial_cmp(&1.0);
+ /// assert_eq!(result, None);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+ /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 < 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 < 1.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn lt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 <= 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 <= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn le(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 > 2.0;
+ /// assert_eq!(result, false);
+ ///
+ /// let result = 2.0 > 2.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn gt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 2.0 >= 1.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 >= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ge(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+ }
+
+ #[doc(alias = "<")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Ord: Eq + PartialOrd<Self> {
+ /// This method returns an [`Ordering`] between `self` and `other`.
+ ///
+ /// By convention, `self.cmp(&other)` returns the ordering matching the expression
+ /// `self <operator> other` if true.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// assert_eq!(5.cmp(&10), Ordering::Less);
+ /// assert_eq!(10.cmp(&5), Ordering::Greater);
+ /// assert_eq!(5.cmp(&5), Ordering::Equal);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn cmp(&self, other: &Self) -> Ordering;
+
+ /// Compares and returns the maximum of two values.
+ ///
+ /// Returns the second argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(2, 1.max(2));
+ /// assert_eq!(2, 2.max(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn max(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Compares and returns the minimum of two values.
+ ///
+ /// Returns the first argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(1, 1.min(2));
+ /// assert_eq!(2, 2.min(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn min(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Restrict a value to a certain interval.
+ ///
+ /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
+ /// less than `min`. Otherwise this returns `self`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `min > max`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(clamp)]
+ ///
+ /// assert!((-3).clamp(-2, 1) == -2);
+ /// assert!(0.clamp(-2, 1) == 0);
+ /// assert!(2.clamp(-2, 1) == 1);
+ /// ```
+ #[must_use]
+ #[unstable(feature = "clamp", issue = "44095")]
+ fn clamp(self, min: Self, max: Self) -> Self
+ where
+ Self: Sized,
+ {
+ if self < min {
+ min
+ } else if self > max {
+ max
+ } else {
+ self
+ }
+ }
+ }
+ }
+
+ pub mod intrinsics {
+ #[lang = "discriminant_kind"]
+ pub trait DiscriminantKind {
+ #[lang = "discriminant_type"]
+ type Discriminant;
+ }
+
+ extern "rust-intrinsic" {
+ pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+ }
+ }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+// for comparing discriminant_value
+impl PartialEq for isize {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+// for comparing discriminant_value
+impl PartialOrd for isize {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+impl Eq for i32 {}
+
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl Ord for i32 {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self > *other {
+ Ordering::Greater
+ } else if *self < *other {
+ Ordering::Less
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+#[derive(PartialEq)]
+struct Foo {
+ a: i32,
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ let a = Foo { a: 42i32 };
+ let b = Foo { a: 42i32 };
+ let c = Foo { a: 7i32 };
+
+ if a == b {
+ print("a == b");
+ } else {
+ print("a != b");
+ }
+
+ if a == c {
+ print("a == c");
+ } else {
+ print("a != c");
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/partial-eq-4.rs b/gcc/testsuite/rust/execute/torture/partial-eq-4.rs
new file mode 100644
index 0000000..b6997d8
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/partial-eq-4.rs
@@ -0,0 +1,457 @@
+/* { dg-output "a == b\r*\na != c\r*\n" }*/
+/* { dg-options "-w" } */
+
+#![feature(intrinsics)]
+
+mod core {
+ mod option {
+ // #[rustc_diagnostic_item = "option_type"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Option<T> {
+ /// No value
+ #[lang = "None"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ None,
+ /// Some value `T`
+ #[lang = "Some"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+ }
+ }
+
+ mod marker {
+ #[lang = "phantom_data"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`")]
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {
+ // Empty.
+ }
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(Eq)]`")]
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {
+ // Empty.
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[lang = "sized"]
+ // #[rustc_on_unimplemented(
+ // message = "the size for values of type `{Self}` cannot be known at compilation time",
+ // label = "doesn't have a size known at compile-time"
+ // )]
+ // #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
+ // #[rustc_specialization_trait]
+ pub trait Sized {
+ // Empty.
+ }
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ // #[derive(Clone, Copy, PartialEq, Debug, Hash)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Ordering {
+ /// An ordering where a compared value is less than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Less = -1,
+ /// An ordering where a compared value is equal to another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Equal = 0,
+ /// An ordering where a compared value is greater than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} == {Rhs}`"
+ // )]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Eq: PartialEq<Self> {
+ // this method is used solely by #[deriving] to assert
+ // that every component of a type implements #[deriving]
+ // itself, the current deriving infrastructure means doing this
+ // assertion without using a method on this trait is nearly
+ // impossible.
+ //
+ // This should never be implemented by hand.
+ #[doc(hidden)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+
+ #[lang = "partial_ord"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`"
+ // )]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ /// This method returns an ordering between `self` and `other` values if one exists.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// let result = 1.0.partial_cmp(&2.0);
+ /// assert_eq!(result, Some(Ordering::Less));
+ ///
+ /// let result = 1.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Equal));
+ ///
+ /// let result = 2.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Greater));
+ /// ```
+ ///
+ /// When comparison is impossible:
+ ///
+ /// ```
+ /// let result = f64::NAN.partial_cmp(&1.0);
+ /// assert_eq!(result, None);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+ /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 < 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 < 1.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn lt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 <= 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 <= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn le(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 > 2.0;
+ /// assert_eq!(result, false);
+ ///
+ /// let result = 2.0 > 2.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn gt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 2.0 >= 1.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 >= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ge(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+ }
+
+ #[doc(alias = "<")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Ord: Eq + PartialOrd<Self> {
+ /// This method returns an [`Ordering`] between `self` and `other`.
+ ///
+ /// By convention, `self.cmp(&other)` returns the ordering matching the expression
+ /// `self <operator> other` if true.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// assert_eq!(5.cmp(&10), Ordering::Less);
+ /// assert_eq!(10.cmp(&5), Ordering::Greater);
+ /// assert_eq!(5.cmp(&5), Ordering::Equal);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn cmp(&self, other: &Self) -> Ordering;
+
+ /// Compares and returns the maximum of two values.
+ ///
+ /// Returns the second argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(2, 1.max(2));
+ /// assert_eq!(2, 2.max(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn max(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Compares and returns the minimum of two values.
+ ///
+ /// Returns the first argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(1, 1.min(2));
+ /// assert_eq!(2, 2.min(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn min(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Restrict a value to a certain interval.
+ ///
+ /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
+ /// less than `min`. Otherwise this returns `self`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `min > max`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(clamp)]
+ ///
+ /// assert!((-3).clamp(-2, 1) == -2);
+ /// assert!(0.clamp(-2, 1) == 0);
+ /// assert!(2.clamp(-2, 1) == 1);
+ /// ```
+ #[must_use]
+ #[unstable(feature = "clamp", issue = "44095")]
+ fn clamp(self, min: Self, max: Self) -> Self
+ where
+ Self: Sized,
+ {
+ if self < min {
+ min
+ } else if self > max {
+ max
+ } else {
+ self
+ }
+ }
+ }
+ }
+
+ pub mod intrinsics {
+ #[lang = "discriminant_kind"]
+ pub trait DiscriminantKind {
+ #[lang = "discriminant_type"]
+ type Discriminant;
+ }
+
+ extern "rust-intrinsic" {
+ pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+ }
+ }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+// for comparing discriminant_value
+impl PartialEq for isize {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+// for comparing discriminant_value
+impl PartialOrd for isize {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+impl Eq for i32 {}
+
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl Ord for i32 {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self > *other {
+ Ordering::Greater
+ } else if *self < *other {
+ Ordering::Less
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+#[derive(PartialEq, Eq)]
+struct Foo {
+ a: i32,
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ let a = Foo { a: 42i32 };
+ let b = Foo { a: 42i32 };
+ let c = Foo { a: 7i32 };
+
+ if a == b {
+ print("a == b");
+ } else {
+ print("a != b");
+ }
+
+ if a == c {
+ print("a == c");
+ } else {
+ print("a != c");
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/partial-ord-1.rs b/gcc/testsuite/rust/execute/torture/partial-ord-1.rs
new file mode 100644
index 0000000..a3558e7
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/partial-ord-1.rs
@@ -0,0 +1,101 @@
+/* { dg-output "x == y\r*\nx > z\r*\n" }*/
+#[lang = "sized"]
+pub trait Sized {}
+
+pub enum Option<T> {
+ #[lang = "None"]
+ None,
+ #[lang = "Some"]
+ Some(T),
+}
+
+use Option::{None, Some};
+
+#[lang = "eq"]
+pub trait PartialEq<Rhs: ?Sized = Self> {
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+}
+
+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) -> Option<Ordering>;
+}
+
+// Implement for i32
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+// Implement PartialOrd for i32
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self < *other {
+ Some(Ordering::Less)
+ } else if *self > *other {
+ Some(Ordering::Greater)
+ } else {
+ Some(Ordering::Equal)
+ }
+ }
+}
+
+// Struct with manual PartialEq
+struct Foo {
+ a: i32,
+}
+
+impl PartialEq for Foo {
+ fn eq(&self, other: &Self) -> bool {
+ self.a.eq(&other.a)
+ }
+}
+
+impl PartialOrd for Foo {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ self.a.partial_cmp(&other.a)
+ }
+}
+
+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 = Foo { a: 42 };
+ let y = Foo { a: 42 };
+ let z = Foo { a: 7 };
+
+ match x.partial_cmp(&y) {
+ Some(Ordering::Equal) => print("x == y"),
+ Some(Ordering::Less) => print("x < y"),
+ Some(Ordering::Greater) => print("x > y"),
+ None => print("x ? y"),
+ }
+
+ match x.partial_cmp(&z) {
+ Some(Ordering::Equal) => print("x == z"),
+ Some(Ordering::Less) => print("x < z"),
+ Some(Ordering::Greater) => print("x > z"),
+ None => print("x ? z"),
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/partial-ord-2.rs b/gcc/testsuite/rust/execute/torture/partial-ord-2.rs
new file mode 100644
index 0000000..d3b713f
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/partial-ord-2.rs
@@ -0,0 +1,469 @@
+/* { dg-output "x == y\r*\nx > z\r*\n" }*/
+
+#![feature(intrinsics)]
+
+mod core {
+ mod option {
+ // #[rustc_diagnostic_item = "option_type"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Option<T> {
+ /// No value
+ #[lang = "None"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ None,
+ /// Some value `T`
+ #[lang = "Some"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+ }
+ }
+
+ mod marker {
+ #[lang = "phantom_data"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`")]
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {
+ // Empty.
+ }
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(Eq)]`")]
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {
+ // Empty.
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[lang = "sized"]
+ // #[rustc_on_unimplemented(
+ // message = "the size for values of type `{Self}` cannot be known at compilation time",
+ // label = "doesn't have a size known at compile-time"
+ // )]
+ // #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
+ // #[rustc_specialization_trait]
+ pub trait Sized {
+ // Empty.
+ }
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ // #[derive(Clone, Copy, PartialEq, Debug, Hash)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Ordering {
+ /// An ordering where a compared value is less than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Less = -1,
+ /// An ordering where a compared value is equal to another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Equal = 0,
+ /// An ordering where a compared value is greater than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} == {Rhs}`"
+ // )]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Eq: PartialEq<Self> {
+ // this method is used solely by #[deriving] to assert
+ // that every component of a type implements #[deriving]
+ // itself, the current deriving infrastructure means doing this
+ // assertion without using a method on this trait is nearly
+ // impossible.
+ //
+ // This should never be implemented by hand.
+ #[doc(hidden)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+
+ #[lang = "partial_ord"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`"
+ // )]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ /// This method returns an ordering between `self` and `other` values if one exists.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// let result = 1.0.partial_cmp(&2.0);
+ /// assert_eq!(result, Some(Ordering::Less));
+ ///
+ /// let result = 1.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Equal));
+ ///
+ /// let result = 2.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Greater));
+ /// ```
+ ///
+ /// When comparison is impossible:
+ ///
+ /// ```
+ /// let result = f64::NAN.partial_cmp(&1.0);
+ /// assert_eq!(result, None);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+ /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 < 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 < 1.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn lt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 <= 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 <= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn le(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 > 2.0;
+ /// assert_eq!(result, false);
+ ///
+ /// let result = 2.0 > 2.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn gt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 2.0 >= 1.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 >= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ge(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+ }
+
+ #[doc(alias = "<")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Ord: Eq + PartialOrd<Self> {
+ /// This method returns an [`Ordering`] between `self` and `other`.
+ ///
+ /// By convention, `self.cmp(&other)` returns the ordering matching the expression
+ /// `self <operator> other` if true.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// assert_eq!(5.cmp(&10), Ordering::Less);
+ /// assert_eq!(10.cmp(&5), Ordering::Greater);
+ /// assert_eq!(5.cmp(&5), Ordering::Equal);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn cmp(&self, other: &Self) -> Ordering;
+
+ /// Compares and returns the maximum of two values.
+ ///
+ /// Returns the second argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(2, 1.max(2));
+ /// assert_eq!(2, 2.max(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn max(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Compares and returns the minimum of two values.
+ ///
+ /// Returns the first argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(1, 1.min(2));
+ /// assert_eq!(2, 2.min(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn min(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Restrict a value to a certain interval.
+ ///
+ /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
+ /// less than `min`. Otherwise this returns `self`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `min > max`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(clamp)]
+ ///
+ /// assert!((-3).clamp(-2, 1) == -2);
+ /// assert!(0.clamp(-2, 1) == 0);
+ /// assert!(2.clamp(-2, 1) == 1);
+ /// ```
+ #[must_use]
+ #[unstable(feature = "clamp", issue = "44095")]
+ fn clamp(self, min: Self, max: Self) -> Self
+ where
+ Self: Sized,
+ {
+ if self < min {
+ min
+ } else if self > max {
+ max
+ } else {
+ self
+ }
+ }
+ }
+ }
+
+ pub mod intrinsics {
+ #[lang = "discriminant_kind"]
+ pub trait DiscriminantKind {
+ #[lang = "discriminant_type"]
+ type Discriminant;
+ }
+
+ extern "rust-intrinsic" {
+ pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+ }
+ }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+// for comparing discriminant_value
+impl PartialEq for isize {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+// for comparing discriminant_value
+impl PartialOrd for isize {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+impl Eq for i32 {}
+
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl Ord for i32 {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self > *other {
+ Ordering::Greater
+ } else if *self < *other {
+ Ordering::Less
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+struct Foo {
+ a: i32,
+}
+
+impl PartialEq for Foo {
+ fn eq(&self, other: &'_ Self) -> bool {
+ self.a == other.a
+ }
+}
+
+impl PartialOrd for Foo {
+ fn partial_cmp(&self, other: &'_ Foo) -> Option<::core::cmp::Ordering> {
+ self.a.partial_cmp(&other.a)
+ }
+}
+
+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 = Foo { a: 42 };
+ let y = Foo { a: 42 };
+ let z = Foo { a: 7 };
+
+ match x.partial_cmp(&y) {
+ Option::Some(Ordering::Equal) => print("x == y"),
+ Option::Some(Ordering::Less) => print("x < y"),
+ Option::Some(Ordering::Greater) => print("x > y"),
+ Option::None => print("x ? y"),
+ }
+
+ match x.partial_cmp(&z) {
+ Option::Some(Ordering::Equal) => print("x == z"),
+ Option::Some(Ordering::Less) => print("x < z"),
+ Option::Some(Ordering::Greater) => print("x > z"),
+ Option::None => print("x ? z"),
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/partial-ord-3.rs b/gcc/testsuite/rust/execute/torture/partial-ord-3.rs
new file mode 100644
index 0000000..7aec07c
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/partial-ord-3.rs
@@ -0,0 +1,489 @@
+/* { dg-output "x == y\r*\nx > z\r*\nx < z\r*\nx >= y\r*\nx <= y\r*\n" } */
+/* { dg-options "-w" } */
+
+#![feature(intrinsics)]
+
+mod core {
+ mod option {
+ // #[rustc_diagnostic_item = "option_type"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Option<T> {
+ /// No value
+ #[lang = "None"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ None,
+ /// Some value `T`
+ #[lang = "Some"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+ }
+ }
+
+ mod marker {
+ #[lang = "phantom_data"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`")]
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {
+ // Empty.
+ }
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(Eq)]`")]
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {
+ // Empty.
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[lang = "sized"]
+ // #[rustc_on_unimplemented(
+ // message = "the size for values of type `{Self}` cannot be known at compilation time",
+ // label = "doesn't have a size known at compile-time"
+ // )]
+ // #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
+ // #[rustc_specialization_trait]
+ pub trait Sized {
+ // Empty.
+ }
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ // #[derive(Clone, Copy, PartialEq, Debug, Hash)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Ordering {
+ /// An ordering where a compared value is less than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Less = -1,
+ /// An ordering where a compared value is equal to another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Equal = 0,
+ /// An ordering where a compared value is greater than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} == {Rhs}`"
+ // )]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Eq: PartialEq<Self> {
+ // this method is used solely by #[deriving] to assert
+ // that every component of a type implements #[deriving]
+ // itself, the current deriving infrastructure means doing this
+ // assertion without using a method on this trait is nearly
+ // impossible.
+ //
+ // This should never be implemented by hand.
+ #[doc(hidden)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+
+ #[lang = "partial_ord"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`"
+ // )]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ /// This method returns an ordering between `self` and `other` values if one exists.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// let result = 1.0.partial_cmp(&2.0);
+ /// assert_eq!(result, Some(Ordering::Less));
+ ///
+ /// let result = 1.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Equal));
+ ///
+ /// let result = 2.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Greater));
+ /// ```
+ ///
+ /// When comparison is impossible:
+ ///
+ /// ```
+ /// let result = f64::NAN.partial_cmp(&1.0);
+ /// assert_eq!(result, None);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+ /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 < 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 < 1.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn lt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 <= 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 <= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn le(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 > 2.0;
+ /// assert_eq!(result, false);
+ ///
+ /// let result = 2.0 > 2.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn gt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 2.0 >= 1.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 >= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ge(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+ }
+
+ #[doc(alias = "<")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Ord: Eq + PartialOrd<Self> {
+ /// This method returns an [`Ordering`] between `self` and `other`.
+ ///
+ /// By convention, `self.cmp(&other)` returns the ordering matching the expression
+ /// `self <operator> other` if true.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// assert_eq!(5.cmp(&10), Ordering::Less);
+ /// assert_eq!(10.cmp(&5), Ordering::Greater);
+ /// assert_eq!(5.cmp(&5), Ordering::Equal);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn cmp(&self, other: &Self) -> Ordering;
+
+ /// Compares and returns the maximum of two values.
+ ///
+ /// Returns the second argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(2, 1.max(2));
+ /// assert_eq!(2, 2.max(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn max(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Compares and returns the minimum of two values.
+ ///
+ /// Returns the first argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(1, 1.min(2));
+ /// assert_eq!(2, 2.min(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn min(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Restrict a value to a certain interval.
+ ///
+ /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
+ /// less than `min`. Otherwise this returns `self`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `min > max`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(clamp)]
+ ///
+ /// assert!((-3).clamp(-2, 1) == -2);
+ /// assert!(0.clamp(-2, 1) == 0);
+ /// assert!(2.clamp(-2, 1) == 1);
+ /// ```
+ #[must_use]
+ #[unstable(feature = "clamp", issue = "44095")]
+ fn clamp(self, min: Self, max: Self) -> Self
+ where
+ Self: Sized,
+ {
+ if self < min {
+ min
+ } else if self > max {
+ max
+ } else {
+ self
+ }
+ }
+ }
+ }
+
+ pub mod intrinsics {
+ #[lang = "discriminant_kind"]
+ pub trait DiscriminantKind {
+ #[lang = "discriminant_type"]
+ type Discriminant;
+ }
+
+ extern "rust-intrinsic" {
+ pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+ }
+ }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+// for comparing discriminant_value
+impl PartialEq for isize {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+// for comparing discriminant_value
+impl PartialOrd for isize {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+impl Eq for i32 {}
+
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl Ord for i32 {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self > *other {
+ Ordering::Greater
+ } else if *self < *other {
+ Ordering::Less
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+struct Foo {
+ a: i32,
+}
+
+impl PartialEq for Foo {
+ fn eq(&self, other: &Self) -> bool {
+ self.a == other.a
+ }
+}
+impl Eq for Foo {}
+
+impl PartialOrd for Foo {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ self.a.partial_cmp(&other.a)
+ }
+}
+
+impl Ord for Foo {
+ fn cmp(&self, other: &Self) -> Ordering {
+ self.a.cmp(&other.a)
+ }
+}
+
+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 = Foo { a: 42 };
+ let y = Foo { a: 42 };
+ let z = Foo { a: 7 };
+
+ // test direct equality
+ if x == y {
+ print("x == y");
+ }
+
+ // test PartialOrd via match
+ match x.partial_cmp(&z) {
+ Option::Some(Ordering::Greater) => print("x > z"),
+ _ => print("x ? z"),
+ }
+
+ // test `<` directly
+ if z < x {
+ print("x < z");
+ }
+
+ // test `>=`
+ if x >= y {
+ print("x >= y");
+ }
+
+ // test `<=`
+ if x <= y {
+ print("x <= y");
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/partial-ord-4.rs b/gcc/testsuite/rust/execute/torture/partial-ord-4.rs
new file mode 100644
index 0000000..fd52f32
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/partial-ord-4.rs
@@ -0,0 +1,115 @@
+/* { dg-output "a == b\r*\na != c\r*\n" }*/
+/* { dg-options "-w" } */
+
+#![feature(intrinsics)]
+
+mod core {
+ mod option {
+ pub enum Option<T> {
+ #[lang = "None"]
+ None,
+ #[lang = "Some"]
+ Some(T),
+ }
+ }
+
+ mod marker {
+ #[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)
+ }
+ }
+
+ #[lang = "partial_ord"]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+ }
+ }
+}
+
+use core::cmp::{Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+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::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+}
+
+struct Foo {
+ a: i32,
+}
+
+impl PartialEq for Foo {
+ fn eq(&self, other: &'_ Self) -> bool {
+ self.a == other.a
+ }
+}
+
+impl PartialOrd for Foo {
+ fn partial_cmp(&self, other: &'_ Foo) -> Option<::core::cmp::Ordering> {
+ ::core::cmp::PartialOrd::partial_cmp(&self.a, &other.a)
+ }
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ let a = Foo { a: 42i32 };
+ let b = Foo { a: 42i32 };
+ let c = Foo { a: 7i32 };
+
+ if a == b {
+ print("a == b");
+ } else {
+ print("a != b");
+ }
+
+ if a == c {
+ print("a == c");
+ } else {
+ print("a != c");
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/partial-ord-5.rs b/gcc/testsuite/rust/execute/torture/partial-ord-5.rs
new file mode 100644
index 0000000..721d2aa
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/partial-ord-5.rs
@@ -0,0 +1,487 @@
+/* { dg-output "a == b\r*\na != c\r*\na >= c\r*\na <= b\r*\na > c\r*\nc < b\r*\n" } */
+/* { dg-options "-w" } */
+
+#![feature(intrinsics)]
+
+mod core {
+ mod option {
+ // #[rustc_diagnostic_item = "option_type"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Option<T> {
+ /// No value
+ #[lang = "None"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ None,
+ /// Some value `T`
+ #[lang = "Some"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+ }
+ }
+
+ mod marker {
+ #[lang = "phantom_data"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`")]
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {
+ // Empty.
+ }
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(Eq)]`")]
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {
+ // Empty.
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[lang = "sized"]
+ // #[rustc_on_unimplemented(
+ // message = "the size for values of type `{Self}` cannot be known at compilation time",
+ // label = "doesn't have a size known at compile-time"
+ // )]
+ // #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
+ // #[rustc_specialization_trait]
+ pub trait Sized {
+ // Empty.
+ }
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ // #[derive(Clone, Copy, PartialEq, Debug, Hash)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Ordering {
+ /// An ordering where a compared value is less than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Less = -1,
+ /// An ordering where a compared value is equal to another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Equal = 0,
+ /// An ordering where a compared value is greater than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} == {Rhs}`"
+ // )]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Eq: PartialEq<Self> {
+ // this method is used solely by #[deriving] to assert
+ // that every component of a type implements #[deriving]
+ // itself, the current deriving infrastructure means doing this
+ // assertion without using a method on this trait is nearly
+ // impossible.
+ //
+ // This should never be implemented by hand.
+ #[doc(hidden)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+
+ #[lang = "partial_ord"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`"
+ // )]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ /// This method returns an ordering between `self` and `other` values if one exists.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// let result = 1.0.partial_cmp(&2.0);
+ /// assert_eq!(result, Some(Ordering::Less));
+ ///
+ /// let result = 1.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Equal));
+ ///
+ /// let result = 2.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Greater));
+ /// ```
+ ///
+ /// When comparison is impossible:
+ ///
+ /// ```
+ /// let result = f64::NAN.partial_cmp(&1.0);
+ /// assert_eq!(result, None);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+ /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 < 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 < 1.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn lt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 <= 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 <= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn le(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 > 2.0;
+ /// assert_eq!(result, false);
+ ///
+ /// let result = 2.0 > 2.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn gt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 2.0 >= 1.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 >= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ge(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+ }
+
+ #[doc(alias = "<")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Ord: Eq + PartialOrd<Self> {
+ /// This method returns an [`Ordering`] between `self` and `other`.
+ ///
+ /// By convention, `self.cmp(&other)` returns the ordering matching the expression
+ /// `self <operator> other` if true.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// assert_eq!(5.cmp(&10), Ordering::Less);
+ /// assert_eq!(10.cmp(&5), Ordering::Greater);
+ /// assert_eq!(5.cmp(&5), Ordering::Equal);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn cmp(&self, other: &Self) -> Ordering;
+
+ /// Compares and returns the maximum of two values.
+ ///
+ /// Returns the second argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(2, 1.max(2));
+ /// assert_eq!(2, 2.max(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn max(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Compares and returns the minimum of two values.
+ ///
+ /// Returns the first argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(1, 1.min(2));
+ /// assert_eq!(2, 2.min(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn min(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Restrict a value to a certain interval.
+ ///
+ /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
+ /// less than `min`. Otherwise this returns `self`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `min > max`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(clamp)]
+ ///
+ /// assert!((-3).clamp(-2, 1) == -2);
+ /// assert!(0.clamp(-2, 1) == 0);
+ /// assert!(2.clamp(-2, 1) == 1);
+ /// ```
+ #[must_use]
+ #[unstable(feature = "clamp", issue = "44095")]
+ fn clamp(self, min: Self, max: Self) -> Self
+ where
+ Self: Sized,
+ {
+ if self < min {
+ min
+ } else if self > max {
+ max
+ } else {
+ self
+ }
+ }
+ }
+ }
+
+ pub mod intrinsics {
+ #[lang = "discriminant_kind"]
+ pub trait DiscriminantKind {
+ #[lang = "discriminant_type"]
+ type Discriminant;
+ }
+
+ extern "rust-intrinsic" {
+ pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+ }
+ }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+// for comparing discriminant_value
+impl PartialEq for isize {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+// for comparing discriminant_value
+impl PartialOrd for isize {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl PartialEq for i32 {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+impl Eq for i32 {}
+
+impl PartialOrd for i32 {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl Ord for i32 {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self > *other {
+ Ordering::Greater
+ } else if *self < *other {
+ Ordering::Less
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+#[derive(PartialEq, Eq, Ord)]
+struct Foo {
+ a: i32,
+}
+
+impl PartialOrd for Foo {
+ fn partial_cmp(&self, other: &'_ Foo) -> Option<::core::cmp::Ordering> {
+ self.a.partial_cmp(&other.a)
+ }
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ let a = Foo { a: 42 };
+ let b = Foo { a: 42 };
+ let c = Foo { a: 7 };
+
+ if a == b {
+ print("a == b");
+ } else {
+ print("a != b");
+ }
+
+ if a != c {
+ print("a != c");
+ } else {
+ print("a == c");
+ }
+
+ if a < c {
+ print("a < c");
+ } else {
+ print("a >= c");
+ }
+
+ if a <= b {
+ print("a <= b");
+ } else {
+ print("a > b");
+ }
+
+ if a > c {
+ print("a > c");
+ } else {
+ print("a <= c");
+ }
+
+ if c >= b {
+ print("c >= b");
+ } else {
+ print("c < b");
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/partial-ord-6.rs b/gcc/testsuite/rust/execute/torture/partial-ord-6.rs
new file mode 100644
index 0000000..5d64f8c
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/partial-ord-6.rs
@@ -0,0 +1,518 @@
+// { dg-additional-options "-w" }
+/* { dg-output "Foo A < B\r?\nFoo B < C\r?\nFoo C == C\r?\nBar x < y\r?\nBarFull s1 < s2\r?\n" } */
+
+#![feature(intrinsics)]
+
+mod core {
+ mod option {
+ // #[rustc_diagnostic_item = "option_type"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Option<T> {
+ /// No value
+ #[lang = "None"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ None,
+ /// Some value `T`
+ #[lang = "Some"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+ }
+ }
+
+ mod marker {
+ #[lang = "phantom_data"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub struct PhantomData<T: ?Sized>;
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`")]
+ #[lang = "structural_peq"]
+ pub trait StructuralPartialEq {
+ // Empty.
+ }
+
+ #[unstable(feature = "structural_match", issue = "31434")]
+ // #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(Eq)]`")]
+ #[lang = "structural_teq"]
+ pub trait StructuralEq {
+ // Empty.
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[lang = "sized"]
+ // #[rustc_on_unimplemented(
+ // message = "the size for values of type `{Self}` cannot be known at compilation time",
+ // label = "doesn't have a size known at compile-time"
+ // )]
+ // #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
+ // #[rustc_specialization_trait]
+ pub trait Sized {
+ // Empty.
+ }
+ }
+
+ mod cmp {
+ use super::marker::Sized;
+ use super::option::Option;
+
+ // #[derive(Clone, Copy, PartialEq, Debug, Hash)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub enum Ordering {
+ /// An ordering where a compared value is less than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Less = -1,
+ /// An ordering where a compared value is equal to another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Equal = 0,
+ /// An ordering where a compared value is greater than another.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ Greater = 1,
+ }
+
+ #[lang = "eq"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} == {Rhs}`"
+ // )]
+ pub trait PartialEq<Rhs: ?Sized = Self> {
+ /// This method tests for `self` and `other` values to be equal, and is used
+ /// by `==`.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn eq(&self, other: &Rhs) -> bool;
+
+ fn ne(&self, other: &Rhs) -> bool {
+ !self.eq(other)
+ }
+ }
+
+ #[doc(alias = "==")]
+ #[doc(alias = "!=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Eq: PartialEq<Self> {
+ // this method is used solely by #[deriving] to assert
+ // that every component of a type implements #[deriving]
+ // itself, the current deriving infrastructure means doing this
+ // assertion without using a method on this trait is nearly
+ // impossible.
+ //
+ // This should never be implemented by hand.
+ #[doc(hidden)]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn assert_receiver_is_total_eq(&self) {}
+ }
+
+ #[lang = "partial_ord"]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ // #[rustc_on_unimplemented(
+ // message = "can't compare `{Self}` with `{Rhs}`",
+ // label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`"
+ // )]
+ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+ /// This method returns an ordering between `self` and `other` values if one exists.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// let result = 1.0.partial_cmp(&2.0);
+ /// assert_eq!(result, Some(Ordering::Less));
+ ///
+ /// let result = 1.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Equal));
+ ///
+ /// let result = 2.0.partial_cmp(&1.0);
+ /// assert_eq!(result, Some(Ordering::Greater));
+ /// ```
+ ///
+ /// When comparison is impossible:
+ ///
+ /// ```
+ /// let result = f64::NAN.partial_cmp(&1.0);
+ /// assert_eq!(result, None);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+ /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 < 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 < 1.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn lt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 <= 2.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 <= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn le(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Less | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 1.0 > 2.0;
+ /// assert_eq!(result, false);
+ ///
+ /// let result = 2.0 > 2.0;
+ /// assert_eq!(result, false);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn gt(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater) => true,
+ _ => false,
+ }
+ }
+
+ /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
+ /// operator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let result = 2.0 >= 1.0;
+ /// assert_eq!(result, true);
+ ///
+ /// let result = 2.0 >= 2.0;
+ /// assert_eq!(result, true);
+ /// ```
+ #[inline]
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn ge(&self, other: &Rhs) -> bool {
+ match self.partial_cmp(other) {
+ Option::Some(Ordering::Greater | Ordering::Equal) => true,
+ _ => false,
+ }
+ }
+ }
+
+ #[doc(alias = "<")]
+ #[doc(alias = ">")]
+ #[doc(alias = "<=")]
+ #[doc(alias = ">=")]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub trait Ord: Eq + PartialOrd<Self> {
+ /// This method returns an [`Ordering`] between `self` and `other`.
+ ///
+ /// By convention, `self.cmp(&other)` returns the ordering matching the expression
+ /// `self <operator> other` if true.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cmp::Ordering;
+ ///
+ /// assert_eq!(5.cmp(&10), Ordering::Less);
+ /// assert_eq!(10.cmp(&5), Ordering::Greater);
+ /// assert_eq!(5.cmp(&5), Ordering::Equal);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn cmp(&self, other: &Self) -> Ordering;
+
+ /// Compares and returns the maximum of two values.
+ ///
+ /// Returns the second argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(2, 1.max(2));
+ /// assert_eq!(2, 2.max(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn max(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Compares and returns the minimum of two values.
+ ///
+ /// Returns the first argument if the comparison determines them to be equal.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(1, 1.min(2));
+ /// assert_eq!(2, 2.min(2));
+ /// ```
+ #[stable(feature = "ord_max_min", since = "1.21.0")]
+ #[must_use]
+ fn min(self, other: Self) -> Self
+ where
+ Self: Sized,
+ {
+ self
+ }
+
+ /// Restrict a value to a certain interval.
+ ///
+ /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
+ /// less than `min`. Otherwise this returns `self`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `min > max`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(clamp)]
+ ///
+ /// assert!((-3).clamp(-2, 1) == -2);
+ /// assert!(0.clamp(-2, 1) == 0);
+ /// assert!(2.clamp(-2, 1) == 1);
+ /// ```
+ #[must_use]
+ #[unstable(feature = "clamp", issue = "44095")]
+ fn clamp(self, min: Self, max: Self) -> Self
+ where
+ Self: Sized,
+ {
+ if self < min {
+ min
+ } else if self > max {
+ max
+ } else {
+ self
+ }
+ }
+ }
+ }
+
+ pub mod intrinsics {
+ #[lang = "discriminant_kind"]
+ pub trait DiscriminantKind {
+ #[lang = "discriminant_type"]
+ type Discriminant;
+ }
+
+ extern "rust-intrinsic" {
+ pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+ }
+ }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+// for comparing discriminant_value
+impl PartialEq for isize {
+ fn eq(&self, other: &Self) -> bool {
+ *self == *other
+ }
+}
+
+// for comparing discriminant_value
+impl PartialOrd for isize {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if *self > *other {
+ Option::Some(Ordering::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+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::Greater)
+ } else if *self < *other {
+ Option::Some(Ordering::Less)
+ } else {
+ Option::Some(Ordering::Equal)
+ }
+ }
+
+ fn lt(&self, other: &Self) -> bool {
+ *self < *other
+ }
+ fn le(&self, other: &Self) -> bool {
+ *self <= *other
+ }
+ fn ge(&self, other: &Self) -> bool {
+ *self >= *other
+ }
+ fn gt(&self, other: &Self) -> bool {
+ *self > *other
+ }
+}
+
+impl Ord for i32 {
+ fn cmp(&self, other: &Self) -> Ordering {
+ if *self > *other {
+ Ordering::Greater
+ } else if *self < *other {
+ Ordering::Less
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+impl Eq for i32 {}
+
+#[derive(PartialEq, PartialOrd)]
+enum Foo {
+ A,
+ B(i32, i32, i32),
+ C { inner: i32, outer: i32 },
+}
+
+#[derive(Ord, PartialOrd, PartialEq, Eq)]
+struct Bar {
+ a: i32,
+}
+
+#[derive(Ord, PartialOrd, PartialEq, Eq)]
+struct BarFull {
+ a: i32,
+ b: i32,
+ c: i32,
+ d: i32,
+}
+
+extern "C" {
+ fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+ unsafe {
+ puts(s as *const str as *const i8);
+ }
+}
+
+fn main() -> i32 {
+ // Enum comparison
+ let a = Foo::A;
+ let b = Foo::B(15, 14, 13);
+ let c = Foo::C {
+ inner: 10,
+ outer: 20,
+ };
+
+ match a.partial_cmp(&b) {
+ Option::Some(Ordering::Less) => print("Foo A < B"),
+ Option::Some(Ordering::Greater) => print("Foo A > B"),
+ Option::Some(Ordering::Equal) => print("Foo A == B"),
+ _ => print("Foo A ? B"),
+ }
+
+ match b.partial_cmp(&c) {
+ Option::Some(Ordering::Less) => print("Foo B < C"),
+ Option::Some(Ordering::Greater) => print("Foo B > C"),
+ Option::Some(Ordering::Equal) => print("Foo B == C"),
+ _ => print("Foo B ? C"),
+ }
+
+ match c.partial_cmp(&c) {
+ Option::Some(Ordering::Less) => print("Foo C < C ???"),
+ Option::Some(Ordering::Greater) => print("Foo C > C ???"),
+ Option::Some(Ordering::Equal) => print("Foo C == C"),
+ _ => print("Foo C ? C"),
+ }
+
+ // Struct comparison: Bar
+ let x = Bar { a: 10 };
+ let y = Bar { a: 20 };
+
+ if x < y {
+ print("Bar x < y");
+ } else if x > y {
+ print("Bar x > y");
+ } else {
+ print("Bar x == y");
+ }
+
+ // Struct comparison: BarFull
+ let s1 = BarFull {
+ a: 1,
+ b: 2,
+ c: 3,
+ d: 4,
+ };
+ let s2 = BarFull {
+ a: 1,
+ b: 2,
+ c: 3,
+ d: 5,
+ };
+
+ match s1.cmp(&s2) {
+ Ordering::Less => print("BarFull s1 < s2"),
+ Ordering::Greater => print("BarFull s1 > s2"),
+ Ordering::Equal => print("BarFull s1 == s2"),
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/sip-hasher.rs b/gcc/testsuite/rust/execute/torture/sip-hasher.rs
new file mode 100644
index 0000000..60826a3
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/sip-hasher.rs
@@ -0,0 +1,438 @@
+// { dg-skip-if "" { *-*-* } { "-m32" } { "" } }
+// { dg-options "-w" }
+// { dg-output "Hash: 0x63d53fd2170bbb8c\r*\n" }
+#![feature(intrinsics)]
+#![feature(rustc_attrs)]
+
+#[lang = "sized"]
+trait Sized {}
+
+mod intrinsics {
+ extern "rust-intrinsic" {
+ pub fn wrapping_add<T>(a: T, b: T) -> T;
+ pub fn rotate_left<T>(a: T, b: T) -> T;
+ pub fn offset<T>(ptr: *const T, count: isize) -> *const T;
+ }
+}
+
+#[lang = "add"]
+trait Add<Rhs = Self> {
+ type Output;
+
+ fn add(self, rhs: Rhs) -> Self::Output;
+}
+
+macro_rules! add_impl {
+ ($($t:ty)*) => ($(
+ impl Add for $t {
+ type Output = $t;
+
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ fn add(self, other: $t) -> $t { self + other }
+ }
+
+
+ )*)
+}
+
+add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
+
+impl<T> *const T {
+ pub unsafe fn add(self, count: usize) -> Self {
+ // SAFETY: the caller must uphold the safety contract for `offset`.
+ unsafe { self.offset(count as isize) }
+ }
+
+ pub unsafe fn offset(self, count: isize) -> *const T {
+ // SAFETY: the caller must uphold the safety contract for `offset`.
+ unsafe { intrinsics::offset(self, count) }
+ }
+}
+
+macro_rules! impl_uint {
+ ($($ty:ident = $lang:literal),*) => {
+ $(
+ #[lang = $lang]
+ impl $ty {
+ pub fn wrapping_add(self, rhs: Self) -> Self {
+ intrinsics::wrapping_add(self, rhs)
+ }
+
+ pub fn rotate_left(self, n: u32) -> Self {
+ intrinsics::rotate_left(self, n as Self)
+ }
+
+ pub fn to_le(self) -> Self {
+ #[cfg(target_endian = "little")]
+ {
+ self
+ }
+ #[cfg(not(target_endian = "little"))]
+ {
+ self.swap_bytes()
+ }
+ }
+ }
+ )*
+ }
+}
+
+impl_uint!(
+ u8 = "u8",
+ u16 = "u16",
+ u32 = "u32",
+ u64 = "u64",
+ u128 = "u128",
+ usize = "usize"
+);
+
+#[repr(C)]
+pub(crate) struct SliceComponents {
+ pub(crate) data_address: *const (),
+ pub(crate) metadata: usize,
+}
+
+#[repr(C)]
+pub(crate) union SliceRepr<T> {
+ pub(crate) const_ptr: *const [T],
+ pub(crate) mut_ptr: *mut [T],
+ pub(crate) components: SliceComponents,
+}
+
+impl<T> [T] {
+ pub const fn as_ptr(&self) -> *const T {
+ self as *const [T] as *const T
+ }
+
+ pub unsafe fn get_unchecked(&self, index: usize) -> &T {
+ unsafe { &*self.as_ptr().add(index) }
+ }
+
+ pub fn len(&self) -> usize {
+ unsafe {
+ SliceRepr {
+ const_ptr: self as *const _,
+ }
+ .components
+ .metadata
+ }
+ }
+}
+
+trait HasherTrait {
+ fn write(&mut self, msg: &[u8]);
+ fn finish(&self) -> u64;
+}
+
+mod cmp {
+ pub fn min(a: usize, b: usize) -> usize {
+ if a < b {
+ a
+ } else {
+ b
+ }
+ }
+}
+
+struct PhantomData<T>;
+
+mod mem {
+ extern "rust-intrinsic" {
+ fn transmute<T, U>(_: T) -> U;
+ fn size_of<T>() -> usize;
+ }
+}
+
+mod ptr {
+ extern "rust-intrinsic" {
+ fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+ }
+}
+
+#[repr(C)]
+struct State {
+ v0: u64,
+ v2: u64,
+ v1: u64,
+ v3: u64,
+}
+
+struct Hasher<S: Sip> {
+ k0: u64,
+ k1: u64,
+ length: usize, // how many bytes we've processed
+ state: State, // hash State
+ tail: u64, // unprocessed bytes le
+ ntail: usize, // how many bytes in tail are valid
+ _marker: PhantomData<S>,
+}
+
+macro_rules! compress {
+ ($state:expr) => {{
+ compress!($state.v0, $state.v1, $state.v2, $state.v3)
+ }};
+ ($v0:expr, $v1:expr, $v2:expr, $v3:expr) => {{
+ $v0 = $v0.wrapping_add($v1);
+ $v1 = $v1.rotate_left(13);
+ $v1 ^= $v0;
+ $v0 = $v0.rotate_left(32);
+ $v2 = $v2.wrapping_add($v3);
+ $v3 = $v3.rotate_left(16);
+ $v3 ^= $v2;
+ $v0 = $v0.wrapping_add($v3);
+ $v3 = $v3.rotate_left(21);
+ $v3 ^= $v0;
+ $v2 = $v2.wrapping_add($v1);
+ $v1 = $v1.rotate_left(17);
+ $v1 ^= $v2;
+ $v2 = $v2.rotate_left(32);
+ }};
+}
+
+#[doc(hidden)]
+trait Sip {
+ fn c_rounds(_: &mut State);
+ fn d_rounds(_: &mut State);
+}
+
+struct Sip13Rounds;
+
+impl Sip for Sip13Rounds {
+ #[inline]
+ fn c_rounds(state: &mut State) {
+ compress!(state);
+ }
+
+ #[inline]
+ fn d_rounds(state: &mut State) {
+ compress!(state);
+ compress!(state);
+ compress!(state);
+ }
+}
+
+struct Sip24Rounds;
+
+impl Sip for Sip24Rounds {
+ #[inline]
+ fn c_rounds(state: &mut State) {
+ compress!(state);
+ compress!(state);
+ }
+
+ #[inline]
+ fn d_rounds(state: &mut State) {
+ compress!(state);
+ compress!(state);
+ compress!(state);
+ compress!(state);
+ }
+}
+
+pub struct SipHasher13 {
+ hasher: Hasher<Sip13Rounds>,
+}
+
+struct SipHasher24 {
+ hasher: Hasher<Sip24Rounds>,
+}
+
+pub struct SipHasher(SipHasher24);
+
+macro_rules! load_int_le {
+ ($buf:expr, $i:expr, $int_ty:ident) => {{
+ let mut data = 0 as $int_ty;
+ ptr::copy_nonoverlapping(
+ $buf.as_ptr().add($i),
+ &mut data as *mut _ as *mut u8,
+ mem::size_of::<$int_ty>(),
+ );
+ data.to_le()
+ }};
+}
+
+#[inline]
+unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 {
+ let mut i = 0; // current byte index (from LSB) in the output u64
+ let mut out = 0;
+ if i + 3 < len {
+ // SAFETY: `i` cannot be greater than `len`, and the caller must guarantee
+ // that the index start..start+len is in bounds.
+ out = unsafe { load_int_le!(buf, start + i, u32) } as u64;
+ i += 4;
+ }
+ if i + 1 < len {
+ // SAFETY: same as above.
+ out |= (unsafe { load_int_le!(buf, start + i, u16) } as u64) << ((i * 8) as u64);
+ i += 2
+ }
+ if i < len {
+ // SAFETY: same as above.
+ out |= (unsafe { *buf.get_unchecked(start + i) } as u64) << ((i * 8) as u64);
+ i += 1;
+ }
+ out
+}
+
+impl SipHasher {
+ #[inline]
+ #[must_use]
+ pub fn new() -> SipHasher {
+ SipHasher::new_with_keys(0, 0)
+ }
+
+ #[inline]
+ #[must_use]
+ pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
+ SipHasher(SipHasher24 {
+ hasher: Hasher::new_with_keys(key0, key1),
+ })
+ }
+}
+
+impl SipHasher13 {
+ #[inline]
+ pub fn new() -> SipHasher13 {
+ SipHasher13::new_with_keys(0, 0)
+ }
+
+ #[inline]
+ pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 {
+ SipHasher13 {
+ hasher: Hasher::new_with_keys(key0, key1),
+ }
+ }
+}
+
+impl<S: Sip> Hasher<S> {
+ #[inline]
+ fn new_with_keys(key0: u64, key1: u64) -> Hasher<S> {
+ let mut state = Hasher {
+ k0: key0,
+ k1: key1,
+ length: 0,
+ state: State {
+ v0: 0,
+ v1: 0,
+ v2: 0,
+ v3: 0,
+ },
+ tail: 0,
+ ntail: 0,
+ _marker: PhantomData,
+ };
+ state.reset();
+ state
+ }
+
+ #[inline]
+ fn reset(&mut self) {
+ self.length = 0;
+ self.state.v0 = self.k0 ^ 0x736f6d6570736575;
+ self.state.v1 = self.k1 ^ 0x646f72616e646f6d;
+ self.state.v2 = self.k0 ^ 0x6c7967656e657261;
+ self.state.v3 = self.k1 ^ 0x7465646279746573;
+ self.ntail = 0;
+ }
+}
+
+impl HasherTrait for SipHasher {
+ #[inline]
+ fn write(&mut self, msg: &[u8]) {
+ self.0.hasher.write(msg)
+ }
+
+ #[inline]
+ fn finish(&self) -> u64 {
+ self.0.hasher.finish()
+ }
+}
+
+impl HasherTrait for SipHasher13 {
+ #[inline]
+ fn write(&mut self, msg: &[u8]) {
+ self.hasher.write(msg)
+ }
+
+ #[inline]
+ fn finish(&self) -> u64 {
+ self.hasher.finish()
+ }
+}
+
+impl<S: Sip> HasherTrait for Hasher<S> {
+ #[inline]
+ fn write(&mut self, msg: &[u8]) {
+ let length = msg.len();
+ self.length += length;
+
+ let mut needed = 0;
+
+ if self.ntail != 0 {
+ needed = 8 - self.ntail;
+ // SAFETY: `cmp::min(length, needed)` is guaranteed to not be over `length`
+ self.tail |=
+ unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << ((8 * self.ntail) as u64);
+ if length < needed {
+ self.ntail += length;
+ return;
+ } else {
+ self.state.v3 ^= self.tail;
+ S::c_rounds(&mut self.state);
+ self.state.v0 ^= self.tail;
+ self.ntail = 0;
+ }
+ }
+
+ // Buffered tail is now flushed, process new input.
+ let len = length - needed;
+ let left = len & 0x7; // len % 8
+
+ let mut i = needed;
+ while i < len - left {
+ let mi = unsafe { load_int_le!(msg, i, u64) };
+
+ self.state.v3 ^= mi;
+ S::c_rounds(&mut self.state);
+ self.state.v0 ^= mi;
+
+ i += 8;
+ }
+
+ self.tail = unsafe { u8to64_le(msg, i, left) };
+ self.ntail = left;
+ }
+
+ #[inline]
+ fn finish(&self) -> u64 {
+ let mut state = self.state;
+
+ let b: u64 = ((self.length as u64 & 0xff) << 56) | self.tail;
+
+ state.v3 ^= b;
+ S::c_rounds(&mut state);
+ state.v0 ^= b;
+
+ state.v2 ^= 0xff;
+ S::d_rounds(&mut state);
+
+ state.v0 ^ state.v1 ^ state.v2 ^ state.v3
+ }
+}
+
+extern "C" {
+ fn printf(fmt: *const u8, ...) -> i32;
+}
+
+fn main() -> i32 {
+ let mut hasher = SipHasher::new_with_keys(0x0706050403020100, 0x0f0e0d0c0b0a0908);
+ hasher.write(b"Hello");
+ let result = hasher.finish();
+
+ unsafe {
+ printf("Hash: 0x%016llx\n\0" as *const str as *const u8, result);
+ }
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/struct-pattern-match.rs b/gcc/testsuite/rust/execute/torture/struct-pattern-match.rs
new file mode 100644
index 0000000..6aec51f
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/struct-pattern-match.rs
@@ -0,0 +1,13 @@
+enum Foo {
+ A { x: i32 },
+ B { y: i32 }
+}
+
+fn main() -> i32 {
+ let x = Foo::A { x: 12 };
+ match x {
+ Foo::A { x: 10 } => 1,
+ Foo::B { y: 11 } => 2,
+ Foo::A { x: abc } => { abc - 12 }
+ }
+}
diff --git a/gcc/testsuite/rust/execute/torture/struct_pattern1.rs b/gcc/testsuite/rust/execute/torture/struct_pattern1.rs
new file mode 100644
index 0000000..7a74092
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/struct_pattern1.rs
@@ -0,0 +1,19 @@
+struct A {
+ // the two warnings are invalid but this should be fixed by our lint rework
+ // with this year's GSoC so ok for now
+ a: i32, // { dg-warning "never read" }
+ b: i32, // { dg-warning "never read" }
+}
+
+fn main() -> i32 {
+ let a = A { a: 15, b: 14 };
+
+ let result = match a {
+ A {
+ a: self_a,
+ b: self_b,
+ } => self_a + self_b,
+ };
+
+ result - 29
+}
diff --git a/gcc/testsuite/rust/execute/torture/trait10.rs b/gcc/testsuite/rust/execute/torture/trait10.rs
index a595122..4e576eb 100644
--- a/gcc/testsuite/rust/execute/torture/trait10.rs
+++ b/gcc/testsuite/rust/execute/torture/trait10.rs
@@ -26,7 +26,6 @@ impl Bar for Foo {
struct S;
impl S {
fn dynamic_dispatch(self, t: &dyn Bar) {
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
t.baz();
}
}
diff --git a/gcc/testsuite/rust/execute/torture/trait11.rs b/gcc/testsuite/rust/execute/torture/trait11.rs
index 093343c..cca084a 100644
--- a/gcc/testsuite/rust/execute/torture/trait11.rs
+++ b/gcc/testsuite/rust/execute/torture/trait11.rs
@@ -13,7 +13,6 @@ trait FnLike<A, R> {
struct S;
impl<'a, T> FnLike<&'a T, &'a T> for S {
fn call(&self, arg: &'a T) -> &'a T {
- // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
arg
}
}
diff --git a/gcc/testsuite/rust/execute/torture/trait12.rs b/gcc/testsuite/rust/execute/torture/trait12.rs
index 83cf107..d174a89 100644
--- a/gcc/testsuite/rust/execute/torture/trait12.rs
+++ b/gcc/testsuite/rust/execute/torture/trait12.rs
@@ -16,7 +16,6 @@ struct Identity;
impl<'a, T> FnLike<&'a T, &'a T> for Identity {
fn call(&self, arg: &'a T) -> &'a T {
- // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
arg
}
}
diff --git a/gcc/testsuite/rust/execute/torture/trait13.rs b/gcc/testsuite/rust/execute/torture/trait13.rs
index 928a37c..0d8f894 100644
--- a/gcc/testsuite/rust/execute/torture/trait13.rs
+++ b/gcc/testsuite/rust/execute/torture/trait13.rs
@@ -11,7 +11,6 @@ trait Bar {
fn baz(&self);
fn qux(&self) {
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
unsafe {
let a = "%i\n\0";
let b = a as *const str;
diff --git a/gcc/testsuite/rust/execute/torture/trait9.rs b/gcc/testsuite/rust/execute/torture/trait9.rs
index a1642f6..f60554a 100644
--- a/gcc/testsuite/rust/execute/torture/trait9.rs
+++ b/gcc/testsuite/rust/execute/torture/trait9.rs
@@ -13,7 +13,6 @@ trait FnLike<A, R> {
struct S;
impl<T> FnLike<&T, &T> for S {
fn call(&self, arg: &T) -> &T {
- // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
arg
}
}
diff --git a/gcc/testsuite/rust/execute/xfail/match-identifierpattern-enum.rs b/gcc/testsuite/rust/execute/xfail/match-identifierpattern-enum.rs
new file mode 100644
index 0000000..c3a0f65
--- /dev/null
+++ b/gcc/testsuite/rust/execute/xfail/match-identifierpattern-enum.rs
@@ -0,0 +1,15 @@
+enum Foo {
+ I(i32),
+}
+
+fn main() -> i32 {
+ let x = Foo::I(0);
+ let ret = 1;
+
+ match x {
+ _ @ Foo::I(b) => { ret = b },
+ _ => {},
+ };
+
+ ret
+}