diff options
Diffstat (limited to 'gcc/testsuite/rust/compile')
337 files changed, 5096 insertions, 241 deletions
diff --git a/gcc/testsuite/rust/compile/additional-trait-bounds1.rs b/gcc/testsuite/rust/compile/additional-trait-bounds1.rs new file mode 100644 index 0000000..449a72f --- /dev/null +++ b/gcc/testsuite/rust/compile/additional-trait-bounds1.rs @@ -0,0 +1,10 @@ +#![feature(optin_builtin_traits)] + +pub unsafe auto trait Send {} +#[lang = "sync"] +pub unsafe auto trait Sync {} + +trait A {} + +impl dyn A + Send {} +impl dyn A + Send + Sync {} diff --git a/gcc/testsuite/rust/compile/additional-trait-bounds2.rs b/gcc/testsuite/rust/compile/additional-trait-bounds2.rs new file mode 100644 index 0000000..1c49b75 --- /dev/null +++ b/gcc/testsuite/rust/compile/additional-trait-bounds2.rs @@ -0,0 +1,9 @@ +#![feature(optin_builtin_traits)] + +pub unsafe auto trait Send {} +#[lang = "sync"] +pub unsafe auto trait Sync {} + +trait A {} + +impl dyn A + Send + Sync + NonExist {} // { dg-error "could not resolve type path .NonExist." } diff --git a/gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs b/gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs new file mode 100644 index 0000000..6764f6e --- /dev/null +++ b/gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs @@ -0,0 +1,11 @@ +// { dg-additional-options "-frust-name-resolution-2.0" } + +#![feature(optin_builtin_traits)] + +pub unsafe auto trait Send {} +#[lang = "sync"] +pub unsafe auto trait Sync {} + +trait A {} + +impl dyn A + Send + Sync + NonExist {} // { dg-error "could not resolve type path .NonExist." } diff --git a/gcc/testsuite/rust/compile/assume.rs b/gcc/testsuite/rust/compile/assume.rs index 4dc2fef..f7e0bc8 100644 --- a/gcc/testsuite/rust/compile/assume.rs +++ b/gcc/testsuite/rust/compile/assume.rs @@ -1,3 +1,5 @@ +#![feature(intrinsics)] + mod intrinsics { extern "rust-intrinsic" { pub fn assume(value: bool); diff --git a/gcc/testsuite/rust/compile/auto_trait.rs b/gcc/testsuite/rust/compile/auto_trait.rs new file mode 100644 index 0000000..47bd119 --- /dev/null +++ b/gcc/testsuite/rust/compile/auto_trait.rs @@ -0,0 +1 @@ +auto trait Valid {} // { dg-error "auto traits are experimental and possibly buggy" } diff --git a/gcc/testsuite/rust/compile/auto_trait_super_trait.rs b/gcc/testsuite/rust/compile/auto_trait_super_trait.rs index 1080afb..06746e9 100644 --- a/gcc/testsuite/rust/compile/auto_trait_super_trait.rs +++ b/gcc/testsuite/rust/compile/auto_trait_super_trait.rs @@ -1,3 +1,4 @@ +#![feature(optin_builtin_traits)] trait Cold {} auto trait IsCool: Cold {} diff --git a/gcc/testsuite/rust/compile/auto_traits1.rs b/gcc/testsuite/rust/compile/auto_traits1.rs new file mode 100644 index 0000000..192052d --- /dev/null +++ b/gcc/testsuite/rust/compile/auto_traits1.rs @@ -0,0 +1,27 @@ +// { dg-additional-options "-frust-compile-until=typecheck" } + +#![feature(optin_builtin_traits)] + +pub unsafe auto trait Send {} +#[lang = "sync"] +pub unsafe auto trait Sync {} + +trait A { + fn a_method(&self) {} +} + +fn foo(a: &(dyn A + Send + Sync)) { + a.a_method(); +} + +struct S; + +impl A for S { + fn a_method(&self) {} +} + +fn main() { + let s = S; + + foo(&s); +} diff --git a/gcc/testsuite/rust/compile/auto_traits2.rs b/gcc/testsuite/rust/compile/auto_traits2.rs new file mode 100644 index 0000000..382d446 --- /dev/null +++ b/gcc/testsuite/rust/compile/auto_traits2.rs @@ -0,0 +1,25 @@ +#![feature(optin_builtin_traits)] + +pub unsafe auto trait Send {} +#[lang = "sync"] +pub unsafe auto trait Sync {} + +trait A { + fn a_method(&self) {} +} + +fn foo(a: &(dyn A + Send + Sync)) { + a.a_method(); +} + +struct S; + +impl A for S { + fn a_method(&self) {} // { dg-warning "unused name" } +} + +fn main() { + let s = S; + + foo(&s); +} diff --git a/gcc/testsuite/rust/compile/auto_traits4.rs b/gcc/testsuite/rust/compile/auto_traits4.rs new file mode 100644 index 0000000..f1cd1e4 --- /dev/null +++ b/gcc/testsuite/rust/compile/auto_traits4.rs @@ -0,0 +1,14 @@ +#![feature(optin_builtin_traits)] + +unsafe auto trait Send {} +unsafe auto trait Sync {} + +fn take_send(_: &dyn Send) {} +fn take_sync(_: &dyn Sync) {} + +fn main() { + let a = i32; + + take_send(&a); + take_sync(&a); +} diff --git a/gcc/testsuite/rust/compile/black_box.rs b/gcc/testsuite/rust/compile/black_box.rs new file mode 100644 index 0000000..80615af --- /dev/null +++ b/gcc/testsuite/rust/compile/black_box.rs @@ -0,0 +1,28 @@ +// { dg-options "-fdump-tree-gimple" } +#![feature(rustc_attrs)] + +#[lang = "sized"] +pub trait Sized {} + +#[rustc_builtin_macro] +macro_rules! llvm_asm { + () => {}; +} + +pub fn black_box<T>(mut dummy: T) -> T { + unsafe { + // { dg-final { scan-tree-dump-times {memory} 1 gimple } } + llvm_asm!("" : : "r"(&mut dummy) : "memory" : "volatile"); + } + + dummy +} + +fn my_function(a: i32) -> i32 { + a +} + +fn main() { + let dummy: i32 = 42; + let _ = black_box(my_function(dummy)); +} diff --git a/gcc/testsuite/rust/compile/box_syntax_feature_gate.rs b/gcc/testsuite/rust/compile/box_syntax_feature_gate.rs index 8eb5503..5f62a59 100644 --- a/gcc/testsuite/rust/compile/box_syntax_feature_gate.rs +++ b/gcc/testsuite/rust/compile/box_syntax_feature_gate.rs @@ -1,4 +1,6 @@ // { dg-options "-frust-compile-until=lowering" } +#[lang = "owned_box"] +pub struct Box<T>; fn main() { let x: Box<_> = box 1; //{ dg-error "box expression syntax is experimental." "" { target *-*-* } } diff --git a/gcc/testsuite/rust/compile/builtin_macro_include_bytes.rs b/gcc/testsuite/rust/compile/builtin_macro_include_bytes.rs deleted file mode 100644 index 9972c10..0000000 --- a/gcc/testsuite/rust/compile/builtin_macro_include_bytes.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![feature(rustc_attrs)] - -#[rustc_builtin_macro] -macro_rules! include_bytes { - () => {{}}; -} - -fn main () { - let file = "include.txt"; - include_bytes! (file); // { dg-error "argument must be a string literal" "" } - include_bytes! (); // { dg-error "macro takes 1 argument" "" } - include_bytes! ("foo.txt", "bar.txt"); // { dg-error "macro takes 1 argument" "" } - include_bytes! ("builtin_macro_include_bytes.rs"); // ok - include_bytes! ("builtin_macro_include_bytes.rs",); // trailing comma ok -} diff --git a/gcc/testsuite/rust/compile/builtin_macro_include_str.rs b/gcc/testsuite/rust/compile/builtin_macro_include_str.rs deleted file mode 100644 index d6d7a76..0000000 --- a/gcc/testsuite/rust/compile/builtin_macro_include_str.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![feature(rustc_attrs)] - -#[rustc_builtin_macro] -macro_rules! include_str { - () => {{}}; -} - -fn main () { - let file = "include.txt"; - include_str! (file); // { dg-error "argument must be a string literal" "" } - include_str! (); // { dg-error "macro takes 1 argument" "" } - include_str! ("foo.txt", "bar.txt"); // { dg-error "macro takes 1 argument" "" } - include_str! ("builtin_macro_include_str.rs"); // ok - include_str! ("builtin_macro_include_str.rs",); // trailing comma ok - include_str! ("invalid_utf8"); // { dg-error "invalid_utf8 was not a valid utf-8 file" "" } -} diff --git a/gcc/testsuite/rust/compile/builtin_macro_recurse2.rs b/gcc/testsuite/rust/compile/builtin_macro_recurse2.rs deleted file mode 100644 index 2e73ab5..0000000 --- a/gcc/testsuite/rust/compile/builtin_macro_recurse2.rs +++ /dev/null @@ -1,21 +0,0 @@ -// { dg-additional-options "-fdump-tree-gimple" } -#![feature(rustc_attrs)] - -#[rustc_builtin_macro] -macro_rules! concat { - () => {}; -} - -macro_rules! a { - () => { - "hey" - }; - ($($t:tt)*) => { - "ho" - }; -} - -fn main() { - // { dg-final { scan-tree-dump-times {"abheyho"} 1 gimple } } - let _ = concat!("a", 'b', a!(), a!(b c d e f a!()), '\0'); -} diff --git a/gcc/testsuite/rust/compile/cast_float_as_integer.rs b/gcc/testsuite/rust/compile/cast_float_as_integer.rs new file mode 100644 index 0000000..e6b86db --- /dev/null +++ b/gcc/testsuite/rust/compile/cast_float_as_integer.rs @@ -0,0 +1,10 @@ +// { dg-options "-w" } +fn main(){ + let foo:f64 = 13.37; + let _ = foo as i64; + let _ = foo as u64; + let _ = foo as isize; + let _ = foo as usize; + let _ = foo as i8; + let _ = foo as u8; +} diff --git a/gcc/testsuite/rust/compile/cfg-core1.rs b/gcc/testsuite/rust/compile/cfg-core1.rs new file mode 100644 index 0000000..7780cc9 --- /dev/null +++ b/gcc/testsuite/rust/compile/cfg-core1.rs @@ -0,0 +1,12 @@ +// { dg-additional-options "-frust-cfg=A -frust-cfg=B" } + +#[cfg_attr(A, cfg(B))] +struct Foo0; + +#[cfg_attr(A, cfg(C))] +struct Bar0; + +fn main() { + let a = Foo0; + let a = Bar0; // { dg-error "cannot find value" } +} diff --git a/gcc/testsuite/rust/compile/cfg-core2.rs b/gcc/testsuite/rust/compile/cfg-core2.rs new file mode 100644 index 0000000..e346edd --- /dev/null +++ b/gcc/testsuite/rust/compile/cfg-core2.rs @@ -0,0 +1,12 @@ +// { dg-additional-options "-frust-cfg=B" } + +#[cfg(not(any(A, B)))] +struct Foo0; + +#[cfg(not(any(A, C)))] +struct Bar0; + +fn main() { + let a = Foo0; // { dg-error "cannot find value" } + let a = Bar0; +} diff --git a/gcc/testsuite/rust/compile/cmp1.rs b/gcc/testsuite/rust/compile/cmp1.rs new file mode 100644 index 0000000..4da5b1c --- /dev/null +++ b/gcc/testsuite/rust/compile/cmp1.rs @@ -0,0 +1,78 @@ +// { dg-options "-w" } +// taken from https://github.com/rust-lang/rust/blob/e1884a8e3c3e813aada8254edfa120e85bf5ffca/library/core/src/cmp.rs#L98 + +#[lang = "sized"] +pub trait Sized {} + +#[lang = "eq"] +#[stable(feature = "rust1", since = "1.0.0")] +#[doc(alias = "==")] +#[doc(alias = "!=")] +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) + } +} + +enum BookFormat { + Paperback, + Hardback, + Ebook, +} + +impl PartialEq<BookFormat> for BookFormat { + fn eq(&self, other: &BookFormat) -> bool { + self == other + } +} + +pub struct Book { + isbn: i32, + format: BookFormat, +} + +// Implement <Book> == <BookFormat> comparisons +impl PartialEq<BookFormat> for Book { + fn eq(&self, other: &BookFormat) -> bool { + self.format == *other + } +} + +// Implement <BookFormat> == <Book> comparisons +impl PartialEq<Book> for BookFormat { + fn eq(&self, other: &Book) -> bool { + *self == other.format + } +} + +// Implement <Book> == <Book> comparisons +impl PartialEq<Book> for Book { + fn eq(&self, other: &Book) -> bool { + self.isbn == other.isbn + } +} + +pub fn main() { + let b1 = Book { + isbn: 1, + format: BookFormat::Paperback, + }; + let b2 = Book { + isbn: 2, + format: BookFormat::Paperback, + }; + + let _c1: bool = b1 == BookFormat::Paperback; + let _c2: bool = BookFormat::Paperback == b2; + let _c3: bool = b1 != b2; +} diff --git a/gcc/testsuite/rust/compile/const_generics_3.rs b/gcc/testsuite/rust/compile/const_generics_3.rs index e4e9008..524d48d 100644 --- a/gcc/testsuite/rust/compile/const_generics_3.rs +++ b/gcc/testsuite/rust/compile/const_generics_3.rs @@ -1,10 +1,12 @@ -// { dg-additional-options "-w" } +// { dg-additional-options "-w -frust-name-resolution-2.0" } + +#[lang = "sized"] +trait Sized {} const M: usize = 4; struct Foo<T, const N: usize = 1> { - // FIXME: This error is bogus. But having it means parsing is valid! - value: [i32; N], // { dg-error "cannot find value .N. in this scope" } + value: [T; N], } fn main() { diff --git a/gcc/testsuite/rust/compile/const_generics_4.rs b/gcc/testsuite/rust/compile/const_generics_4.rs index b364d3b..2766e4c 100644 --- a/gcc/testsuite/rust/compile/const_generics_4.rs +++ b/gcc/testsuite/rust/compile/const_generics_4.rs @@ -4,4 +4,4 @@ const P: usize = 14; struct Foo<const N: usize = { M }>; // { dg-error "cannot find value .M. in this scope" } struct Bar<const N: usize = { P }>; -struct Baz<const N: NotAType = { P }>; // { dg-error "failed to resolve TypePath: NotAType in this scope" } +struct Baz<const N: NotAType = { P }>; // { dg-error "could not resolve type path .NotAType." } diff --git a/gcc/testsuite/rust/compile/const_generics_7.rs b/gcc/testsuite/rust/compile/const_generics_7.rs index 2c128db..dad4c21 100644 --- a/gcc/testsuite/rust/compile/const_generics_7.rs +++ b/gcc/testsuite/rust/compile/const_generics_7.rs @@ -1,17 +1,17 @@ struct S<const N: usize>; -pub fn foo<const N: FooBar>() {} // { dg-error "failed to resolve" } -type Foo<const N: FooBar> = S<N>; // { dg-error "failed to resolve" } -struct Foo2<const N: FooBar>; // { dg-error "failed to resolve" } -enum Foo3<const N: FooBar> { // { dg-error "failed to resolve" } +pub fn foo<const N: FooBar>() {} // { dg-error "could not resolve" } +type Foo<const N: FooBar> = S<N>; // { dg-error "could not resolve" } +struct Foo2<const N: FooBar>; // { dg-error "could not resolve" } +enum Foo3<const N: FooBar> { // { dg-error "could not resolve" } Foo, Bar, } -union Foo4<const N: FooBar> { // { dg-error "failed to resolve" } +union Foo4<const N: FooBar> { // { dg-error "could not resolve" } a: usize, b: i32, } -trait Fooable<const N: FooBar> {} // { dg-error "failed to resolve" } +trait Fooable<const N: FooBar> {} // { dg-error "could not resolve" } trait Traitable {} -impl<const N: FooBar> Traitable for Foo2<N> {} // { dg-error "failed to resolve" } +impl<const N: FooBar> Traitable for Foo2<N> {} // { dg-error "could not resolve" } diff --git a/gcc/testsuite/rust/compile/crate-metavar1.rs b/gcc/testsuite/rust/compile/crate-metavar1.rs new file mode 100644 index 0000000..45384e1 --- /dev/null +++ b/gcc/testsuite/rust/compile/crate-metavar1.rs @@ -0,0 +1,14 @@ +macro_rules! foo { + () => { + $crate::inner::bar() + } +} + +pub mod inner { + pub fn bar() { } +} + +fn main() { + foo!(); + crate::inner::bar(); +} diff --git a/gcc/testsuite/rust/compile/derive-debug1.rs b/gcc/testsuite/rust/compile/derive-debug1.rs new file mode 100644 index 0000000..cf2187d --- /dev/null +++ b/gcc/testsuite/rust/compile/derive-debug1.rs @@ -0,0 +1,41 @@ +#[lang = "sized"] +trait Sized {} + +mod core { + pub mod result { + pub enum Result<T, E> { + #[lang = "Ok"] + Ok(T), + #[lang = "Err"] + Err(E), + } + } + + mod fmt { + struct Formatter; // { dg-warning "is never constructed" } + struct Error; // { dg-warning "is never constructed" } + + type Result = crate::core::result::Result<(), Error>; + + trait Debug { + fn fmt(&self, fmt: &mut Formatter) -> Result; + } + } +} + +#[derive(Debug)] // { dg-warning "unused name" } +// { dg-warning "stub implementation" "" { target *-*-* } .-1 } +struct Foo { a: i32, b: i64 } // { dg-warning "is never constructed" } + +#[derive(Debug)] // { dg-warning "unused name" } +// { dg-warning "stub implementation" "" { target *-*-* } .-1 } +struct Bar(i32, i32); // { dg-warning "is never constructed" } + +#[derive(Debug)] // { dg-warning "unused name" } +// { dg-warning "stub implementation" "" { target *-*-* } .-1 } +enum Baz { + A, + B(i32), + C { a: i32 } +} + diff --git a/gcc/testsuite/rust/compile/derive-default1.rs b/gcc/testsuite/rust/compile/derive-default1.rs new file mode 100644 index 0000000..902c65e --- /dev/null +++ b/gcc/testsuite/rust/compile/derive-default1.rs @@ -0,0 +1,29 @@ +#[derive(Default)] +struct Foo { _a: i32, _b: i64, _c: u8 } + +#[lang = "sized"] +trait Sized {} + +mod core { + mod default { + trait Default: Sized { + fn default() -> Self; + } + + impl Default for i32 { + fn default() -> Self { 0 } + } + + impl Default for i64 { + fn default() -> Self { 27 } + } + + impl Default for u8 { + fn default() -> Self { 18 } + } + } +} + +fn main() { + let _ = Foo::default(); +} diff --git a/gcc/testsuite/rust/compile/derive-eq-invalid.rs b/gcc/testsuite/rust/compile/derive-eq-invalid.rs new file mode 100644 index 0000000..b0bf856 --- /dev/null +++ b/gcc/testsuite/rust/compile/derive-eq-invalid.rs @@ -0,0 +1,52 @@ +mod core { + mod cmp { + #[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 = "phantom_data"] +struct PhantomData<T>; + +#[lang = "sized"] +trait Sized {} + +#[lang = "structural_peq"] +trait StructuralPartialEq {} + +#[lang = "structural_teq"] +trait StructuralEq {} + +#[derive(PartialEq)] +struct NotEq; + +#[derive(Eq, PartialEq)] // { dg-error "bounds not satisfied for NotEq .Eq." } +struct Container(NotEq); + +// #[derive(Eq)] +// struct Foo { a: i32 } +// #[derive(Eq)] +// struct Bar(i32); + +// #[derive(Eq)] +// enum Baz { +// A, +// B(i32), +// C { a: i32 } +// } + +// #[derive(Eq)] +// union Qux { +// a: i32, +// b: i64, +// } diff --git a/gcc/testsuite/rust/compile/derive-hash1.rs b/gcc/testsuite/rust/compile/derive-hash1.rs new file mode 100644 index 0000000..80e1e2d --- /dev/null +++ b/gcc/testsuite/rust/compile/derive-hash1.rs @@ -0,0 +1,91 @@ +#![feature(intrinsics)] + +#[lang = "sized"] +trait Sized {} + +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; + } + } + + pub mod hash { + pub trait Hasher {} + + pub trait Hash { + /// Feeds this value into the given [`Hasher`]. + /// + /// # Examples + /// + /// ``` + /// use std::collections::hash_map::DefaultHasher; + /// use std::hash::{Hash, Hasher}; + /// + /// let mut hasher = DefaultHasher::new(); + /// 7920.hash(&mut hasher); + /// println!("Hash is {:x}!", hasher.finish()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn hash<H: Hasher>(&self, state: &mut H); + + /// Feeds a slice of this type into the given [`Hasher`]. + /// + /// # Examples + /// + /// ``` + /// use std::collections::hash_map::DefaultHasher; + /// use std::hash::{Hash, Hasher}; + /// + /// let mut hasher = DefaultHasher::new(); + /// let numbers = [6, 28, 496, 8128]; + /// Hash::hash_slice(&numbers, &mut hasher); + /// println!("Hash is {:x}!", hasher.finish()); + /// ``` + #[stable(feature = "hash_slice", since = "1.3.0")] + fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) + where + Self: Sized, + { + // for piece in data { + // piece.hash(state); + // } + } + } + } +} + +impl core::hash::Hash for i32 { + fn hash<H: core::hash::Hasher>(&self, state: &mut H) {} +} + +impl core::hash::Hash for i64 { + fn hash<H: core::hash::Hasher>(&self, state: &mut H) {} +} + +// for the discriminant value +impl core::hash::Hash for isize { + fn hash<H: core::hash::Hasher>(&self, state: &mut H) {} +} + +#[derive(Hash)] +struct Foo { // { dg-warning "never constructed" } + a: i32, + b: i32, +} + +#[derive(Hash)] +struct Bar(i32, i64); // { dg-warning "never constructed" } + +#[derive(Hash)] +enum Baz { + A, + B(i32), + C { a: i64 } +} diff --git a/gcc/testsuite/rust/compile/derive-partialeq1.rs b/gcc/testsuite/rust/compile/derive-partialeq1.rs new file mode 100644 index 0000000..35e33fb --- /dev/null +++ b/gcc/testsuite/rust/compile/derive-partialeq1.rs @@ -0,0 +1,62 @@ +#![feature(intrinsics)] + +#[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, Copy)] // { dg-warning "unused name" } +struct Foo; + +#[derive(PartialEq)] +struct Bar(Foo); + +#[derive(PartialEq)] +struct Baz { _inner: Foo } + +extern "C" { + fn puts(s: *const i8); +} + +fn print(b: bool) { + if b { + unsafe { puts("true" as *const str as *const i8) } + } else { + unsafe { puts("false" as *const str as *const i8) } + } +} + +fn main() -> i32 { + let x = Foo; + + let b1 = x == Foo; + let b2 = Bar(x) != Bar(Foo); + let b3 = Baz { _inner: Foo } != Baz { _inner: x }; + + print(b1); + print(b2); + print(b3); + + 0 +} diff --git a/gcc/testsuite/rust/compile/derive_clone_enum1.rs b/gcc/testsuite/rust/compile/derive_clone_enum1.rs new file mode 100644 index 0000000..947dc5c6 --- /dev/null +++ b/gcc/testsuite/rust/compile/derive_clone_enum1.rs @@ -0,0 +1,16 @@ +#[lang = "clone"] +trait Clone { + pub fn clone(&self) -> Self; +} + +impl Clone for i32 { + fn clone(&self) -> Self { + *self + } +} + +#[derive(Clone)] +enum AllIdentifiers { + A, + B +} diff --git a/gcc/testsuite/rust/compile/derive_clone_enum2.rs b/gcc/testsuite/rust/compile/derive_clone_enum2.rs new file mode 100644 index 0000000..c7a4ad5 --- /dev/null +++ b/gcc/testsuite/rust/compile/derive_clone_enum2.rs @@ -0,0 +1,16 @@ +#[lang = "clone"] +trait Clone { + pub fn clone(&self) -> Self; +} + +impl Clone for i32 { + fn clone(&self) -> Self { + *self + } +} + +#[derive(Clone)] +enum TupleEnum { + A(i32), + B(i32, i32, i32) +} diff --git a/gcc/testsuite/rust/compile/derive_clone_enum3.rs b/gcc/testsuite/rust/compile/derive_clone_enum3.rs new file mode 100644 index 0000000..92fd6ee --- /dev/null +++ b/gcc/testsuite/rust/compile/derive_clone_enum3.rs @@ -0,0 +1,16 @@ +#[lang = "clone"] +trait Clone { + pub fn clone(&self) -> Self; +} + +impl Clone for i32 { + fn clone(&self) -> Self { + *self + } +} + +#[derive(Clone)] +enum StructEnum { + A { i0: i32 }, + B { i0: i32, i1: i32, i2: i32 } +} diff --git a/gcc/testsuite/rust/compile/derive_macro1.rs b/gcc/testsuite/rust/compile/derive_macro1.rs index 779aad78e..bc10d60 100644 --- a/gcc/testsuite/rust/compile/derive_macro1.rs +++ b/gcc/testsuite/rust/compile/derive_macro1.rs @@ -1,6 +1,7 @@ #[lang = "sized"] pub trait Sized {} +#[lang = "clone"] pub trait Clone { fn clone(&self) -> Self; } diff --git a/gcc/testsuite/rust/compile/derive_macro3.rs b/gcc/testsuite/rust/compile/derive_macro3.rs index 1c7d473..ad40cae 100644 --- a/gcc/testsuite/rust/compile/derive_macro3.rs +++ b/gcc/testsuite/rust/compile/derive_macro3.rs @@ -1,6 +1,7 @@ #[lang = "sized"] pub trait Sized {} +#[lang = "clone"] pub trait Clone { fn clone(&self) -> Self; } diff --git a/gcc/testsuite/rust/compile/derive_macro4.rs b/gcc/testsuite/rust/compile/derive_macro4.rs index 7802e8f..8bf1bca 100644 --- a/gcc/testsuite/rust/compile/derive_macro4.rs +++ b/gcc/testsuite/rust/compile/derive_macro4.rs @@ -1,17 +1,17 @@ #[lang = "sized"] pub trait Sized {} +#[lang = "copy"] pub trait Copy {} + +#[lang = "clone"] pub trait Clone { fn clone(&self) -> Self; } +#[lang = "phantom_data"] struct PhantomData<T>; -pub struct AssertParamIsCopy<T: Copy> { - _field: PhantomData<T>, -} - #[derive(Clone)] // { dg-error "bounds not satisfied for U .Copy. is not satisfied" } union U { i: i32, diff --git a/gcc/testsuite/rust/compile/derive_macro6.rs b/gcc/testsuite/rust/compile/derive_macro6.rs index b7bf7a7..412144d 100644 --- a/gcc/testsuite/rust/compile/derive_macro6.rs +++ b/gcc/testsuite/rust/compile/derive_macro6.rs @@ -1,7 +1,10 @@ #[lang = "sized"] pub trait Sized {} +#[lang = "copy"] pub trait Copy {} + +#[lang = "clone"] pub trait Clone { fn clone(&self) -> Self; } @@ -9,10 +12,6 @@ pub trait Clone { #[lang = "phantom_data"] pub struct PhantomData<T>; -pub struct AssertParamIsCopy<T: Copy> { - pub _field: PhantomData<T>, -} - impl Copy for i32 {} impl Copy for i64 {} impl Copy for U {} diff --git a/gcc/testsuite/rust/compile/enum_discriminant1.rs b/gcc/testsuite/rust/compile/enum_discriminant1.rs new file mode 100644 index 0000000..32092b2 --- /dev/null +++ b/gcc/testsuite/rust/compile/enum_discriminant1.rs @@ -0,0 +1,7 @@ +enum Foo { + Bar = 3 + 12, +} + +fn test() -> Foo { // { dg-warning "function is never used" } + return Foo::Bar; +}
\ No newline at end of file diff --git a/gcc/testsuite/rust/compile/enum_discriminant2.rs b/gcc/testsuite/rust/compile/enum_discriminant2.rs new file mode 100644 index 0000000..351dfbb --- /dev/null +++ b/gcc/testsuite/rust/compile/enum_discriminant2.rs @@ -0,0 +1,9 @@ +fn test() -> isize { + 1 +} + +enum Foo { + Bar = test() // { dg-error "only functions marked as .const." } +} + +fn main() {} diff --git a/gcc/testsuite/rust/compile/enum_variant_name.rs b/gcc/testsuite/rust/compile/enum_variant_name.rs new file mode 100644 index 0000000..671fced --- /dev/null +++ b/gcc/testsuite/rust/compile/enum_variant_name.rs @@ -0,0 +1,12 @@ +// { dg-additional-options "-w -frust-name-resolution-2.0" } +struct E1; + +enum Test { + E1 = { + let x = E1; + { + let x = E1; + } + 0 + }, +} diff --git a/gcc/testsuite/rust/compile/exhaustiveness1.rs b/gcc/testsuite/rust/compile/exhaustiveness1.rs new file mode 100644 index 0000000..356636b --- /dev/null +++ b/gcc/testsuite/rust/compile/exhaustiveness1.rs @@ -0,0 +1,51 @@ +struct S { + a: i32, +} + +fn s1(s: S) { + match s { + S { a: _ } => {} + } +} + +fn s2(s: S) { + match s { + _ => {} + } +} + +fn s3(s: S) { + match s {} +} + +enum E { + A(), + B(), + C(), +} + +fn e1(e: E) { + match e { + // { dg-error "non-exhaustive patterns: 'E::B..' not covered" "" { target *-*-* } .-1 } + E::A() => {} + E::C() => {} + } +} + +fn e2(e: E) { + match e { + // { dg-error "non-exhaustive patterns: 'E::A..' not covered" "" { target *-*-* } .-1 } + E::B() => {} + E::C() => {} + } +} + +fn e3(e: E) { + match e { + E::A() => {} + E::B() => {} + E::C() => {} + } +} + +fn main() {} diff --git a/gcc/testsuite/rust/compile/exhaustiveness2.rs b/gcc/testsuite/rust/compile/exhaustiveness2.rs new file mode 100644 index 0000000..f2e0008 --- /dev/null +++ b/gcc/testsuite/rust/compile/exhaustiveness2.rs @@ -0,0 +1,28 @@ +enum E1 { + E2(E2), + None, +} + +enum E2 { + E3(E3), + None, +} + +enum E3 { + S(S), + None, +} + +struct S { + a: i32, + b: u64, +} + +fn f1(e: E1) { + match e { + // { dg-error "non-exhaustive patterns: 'E1::E2.E2::None.' and 'E1::None' not covered" "" { target *-*-* } .-1 } + E1::E2(E2::E3(_)) => {} + } +} + +fn main() {} diff --git a/gcc/testsuite/rust/compile/exhaustiveness3.rs b/gcc/testsuite/rust/compile/exhaustiveness3.rs new file mode 100644 index 0000000..4a5dc1c --- /dev/null +++ b/gcc/testsuite/rust/compile/exhaustiveness3.rs @@ -0,0 +1,55 @@ +struct S { + e1: E1, + e2: E2, +} + +enum E1 { + A(), + B(), + C(), +} + +enum E2 { + D(), + E(), +} + +// This is a valid match +fn f(s: S) { + match s { + S { + e1: E1::A(), + e2: E2::D(), + } => {} + S { + e1: E1::B(), + e2: E2::D(), + } => {} + S { + e1: E1::C(), + e2: E2::D(), + } => {} + S { + e1: E1::A(), + e2: E2::E(), + } => {} + S { + e1: E1::B(), + e2: E2::E(), + } => {} + S { + e1: E1::C(), + e2: E2::E(), + } => {} + } +} + +fn f2(s: S) { + match s { + // { dg-error "non-exhaustive patterns: 'S { e1: E1::B.., e2: E2::D.. }' and 'S { e1: E1::C.., e2: E2::D.. }' not covered" "" { target *-*-* } .-1 } + S { e1: E1::A(), e2: _ } => {} + S { e1: _, e2: E2::E() } => {} + } +} + +fn main() {} diff --git a/gcc/testsuite/rust/compile/extern_generics.rs b/gcc/testsuite/rust/compile/extern_generics.rs new file mode 100644 index 0000000..26f97a6 --- /dev/null +++ b/gcc/testsuite/rust/compile/extern_generics.rs @@ -0,0 +1,8 @@ +#[lang="sized"] +trait Sized {} + + +// E0044 +fn main() { +extern "C" { fn some_func<T>(x: T); } // { dg-error "foreign items may not have type parameters .E0044." } +}
\ No newline at end of file diff --git a/gcc/testsuite/rust/compile/feature.rs b/gcc/testsuite/rust/compile/feature.rs index f743f92..6f428f0 100644 --- a/gcc/testsuite/rust/compile/feature.rs +++ b/gcc/testsuite/rust/compile/feature.rs @@ -2,5 +2,7 @@ #![feature(AA)] //{ dg-error "unknown feature .AA." } #![feature(iamcrabby)] // { dg-error "unknown feature .iamcrabby." } #![feature(nonexistent_gccrs_feature)] // { dg-error "unknown feature .nonexistent_gccrs_feature." } +// ErrorCode - E0556 +#![feature] // { dg-error "malformed .feature. attribute input" } fn main() {} diff --git a/gcc/testsuite/rust/compile/feature_rust_attri0.rs b/gcc/testsuite/rust/compile/feature_rust_attri0.rs index 9c11f56..1937acf 100644 --- a/gcc/testsuite/rust/compile/feature_rust_attri0.rs +++ b/gcc/testsuite/rust/compile/feature_rust_attri0.rs @@ -1,3 +1,7 @@ +extern "C" { + fn printf(s: *const i8, ...); +} + #[rustc_builtin_macro] //{ dg-error "internal implementation detail. " "" { target *-*-* } } macro_rules! line { () => {{}}; @@ -5,7 +9,7 @@ macro_rules! line { fn main() -> i32 { let a = line!(); - print(a); + printf("%d\0" as *const str as *const i8, a); 0 } diff --git a/gcc/testsuite/rust/compile/for-loop1.rs b/gcc/testsuite/rust/compile/for-loop1.rs new file mode 100644 index 0000000..21e0399 --- /dev/null +++ b/gcc/testsuite/rust/compile/for-loop1.rs @@ -0,0 +1,543 @@ +// { dg-output "loop\r*\nloop\r*\n" } +#![feature(intrinsics)] + +pub use option::Option::{self, None, Some}; +pub use result::Result::{self, Err, Ok}; + +extern "C" { + fn printf(s: *const i8, ...); + fn puts(s: *const i8); +} + +mod option { + pub enum Option<T> { + #[lang = "None"] + None, + #[lang = "Some"] + Some(T), + } +} + +mod result { + enum Result<T, E> { + Ok(T), + Err(E), + } +} + +#[lang = "sized"] +pub trait Sized {} + +#[lang = "clone"] +pub trait Clone: Sized { + fn clone(&self) -> Self; + + fn clone_from(&mut self, source: &Self) { + *self = source.clone() + } +} + +mod impls { + use super::Clone; + + macro_rules! impl_clone { + ($($t:ty)*) => { + $( + impl Clone for $t { + fn clone(&self) -> Self { + *self + } + } + )* + } + } + + impl_clone! { + usize u8 u16 u32 u64 // u128 + isize i8 i16 i32 i64 // i128 + f32 f64 + bool char + } +} + +#[lang = "copy"] +pub trait Copy: Clone { + // Empty. +} + +mod copy_impls { + use super::Copy; + + macro_rules! impl_copy { + ($($t:ty)*) => { + $( + impl Copy for $t {} + )* + } + } + + impl_copy! { + usize u8 u16 u32 u64 // u128 + isize i8 i16 i32 i64 // i128 + f32 f64 + bool char + } +} + +mod intrinsics { + extern "rust-intrinsic" { + pub fn add_with_overflow<T>(x: T, y: T) -> (T, bool); + pub fn wrapping_add<T>(a: T, b: T) -> T; + pub fn wrapping_sub<T>(a: T, b: T) -> T; + pub fn rotate_left<T>(a: T, b: T) -> T; + pub fn rotate_right<T>(a: T, b: T) -> T; + pub fn offset<T>(ptr: *const T, count: isize) -> *const T; + pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize); + pub fn move_val_init<T>(dst: *mut T, src: T); + pub fn uninit<T>() -> T; + } +} + +mod ptr { + #[lang = "const_ptr"] + impl<T> *const T { + pub unsafe fn offset(self, count: isize) -> *const T { + crate::intrinsics::offset(self, count) + } + } + + #[lang = "mut_ptr"] + impl<T> *mut T { + pub unsafe fn offset(self, count: isize) -> *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 = 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 crate::mem::size_of::<T>() < 32 { + let z = read(x); + crate::intrinsics::copy_nonoverlapping(y, x, 1); + write(y, z); + } else { + swap_nonoverlapping(x, y, 1); + } + } + + pub unsafe fn write<T>(dst: *mut T, src: T) { + crate::intrinsics::move_val_init(&mut *dst, src) + } + + pub unsafe fn read<T>(src: *const T) -> T { + let mut tmp: T = crate::mem::uninitialized(); + crate::intrinsics::copy_nonoverlapping(src, &mut tmp, 1); + tmp + } + + pub unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) { + struct Block(u64, u64, u64, u64); + struct UnalignedBlock(u64, u64, u64, u64); + + 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 + // N.B. We can't use a for loop as the `range` impl calls `mem::swap` recursively + let mut i: usize = 0; + 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 = 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 + 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 = 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); + + crate::intrinsics::copy_nonoverlapping(x, t, rem); + crate::intrinsics::copy_nonoverlapping(y, x, rem); + crate::intrinsics::copy_nonoverlapping(t, y, rem); + } + } +} + +mod mem { + extern "rust-intrinsic" { + #[rustc_const_stable(feature = "const_transmute", since = "1.46.0")] + pub fn transmute<T, U>(_: T) -> U; + #[rustc_const_stable(feature = "const_size_of", since = "1.40.0")] + pub fn size_of<T>() -> usize; + } + + pub fn swap<T>(x: &mut T, y: &mut T) { + unsafe { + crate::ptr::swap_nonoverlapping_one(x, y); + } + } + + pub fn replace<T>(dest: &mut T, mut src: T) -> T { + swap(dest, &mut src); + src + } + + pub unsafe fn uninitialized<T>() -> T { + crate::intrinsics::uninit() + } +} + +macro_rules! impl_uint { + ($($ty:ident = $lang:literal),*) => { + $( + impl $ty { + pub fn wrapping_add(self, rhs: Self) -> Self { + unsafe { + crate::intrinsics::wrapping_add(self, rhs) + } + } + + pub fn wrapping_sub(self, rhs: Self) -> Self { + unsafe { + crate::intrinsics::wrapping_sub(self, rhs) + } + } + + pub fn rotate_left(self, n: u32) -> Self { + unsafe { + crate::intrinsics::rotate_left(self, n as Self) + } + } + + pub fn rotate_right(self, n: u32) -> Self { + unsafe { + crate::intrinsics::rotate_right(self, n as Self) + } + } + + pub fn to_le(self) -> Self { + #[cfg(target_endian = "little")] + { + self + } + } + + pub const fn from_le_bytes(bytes: [u8; crate::mem::size_of::<Self>()]) -> Self { + Self::from_le(Self::from_ne_bytes(bytes)) + } + + pub const fn from_le(x: Self) -> Self { + #[cfg(target_endian = "little")] + { + x + } + } + + pub const fn from_ne_bytes(bytes: [u8; crate::mem::size_of::<Self>()]) -> Self { + unsafe { crate::mem::transmute(bytes) } + } + + pub fn checked_add(self, rhs: Self) -> Option<Self> { + let (a, b) = self.overflowing_add(rhs); + if b { + Option::None + } else { + Option::Some(a) + } + } + + pub fn overflowing_add(self, rhs: Self) -> (Self, bool) { + let (a, b) = unsafe { crate::intrinsics::add_with_overflow(self as $ty, rhs as $ty) }; + (a as Self, b) + } + } + )* + } +} + +impl_uint!( + u8 = "u8", + u16 = "u16", + u32 = "u32", + u64 = "u64", + usize = "usize" +); + +#[lang = "add"] +pub 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; + + fn add(self, other: $t) -> $t { self + other } + } + )*) +} + +add_impl! { usize u8 u16 u32 u64 /*isize i8 i16 i32 i64*/ f32 f64 } + +#[lang = "sub"] +pub trait Sub<RHS = Self> { + type Output; + + fn sub(self, rhs: RHS) -> Self::Output; +} +macro_rules! sub_impl { + ($($t:ty)*) => ($( + impl Sub for $t { + type Output = $t; + + fn sub(self, other: $t) -> $t { self - other } + } + )*) +} + +sub_impl! { usize u8 u16 u32 u64 /*isize i8 i16 i32 i64*/ f32 f64 } + +#[lang = "Range"] +pub struct Range<Idx> { + pub start: Idx, + pub end: Idx, +} + +pub trait TryFrom<T>: Sized { + /// The type returned in the event of a conversion error. + type Error; + + /// Performs the conversion. + fn try_from(value: T) -> Result<Self, Self::Error>; +} + +pub trait From<T>: Sized { + fn from(_: T) -> Self; +} + +impl<T> From<T> for T { + fn from(t: T) -> T { + t + } +} + +impl<T, U> TryFrom<U> for T +where + T: From<U>, +{ + type Error = !; + + fn try_from(value: U) -> Result<Self, Self::Error> { + Ok(T::from(value)) + } +} + +trait Step { + /// Returns the number of steps between two step objects. The count is + /// inclusive of `start` and exclusive of `end`. + /// + /// Returns `None` if it is not possible to calculate `steps_between` + /// without overflow. + fn steps_between(start: &Self, end: &Self) -> Option<usize>; + + /// Replaces this step with `1`, returning itself + fn replace_one(&mut self) -> Self; + + /// Replaces this step with `0`, returning itself + fn replace_zero(&mut self) -> Self; + + /// Adds one to this step, returning the result + fn add_one(&self) -> Self; + + /// Subtracts one to this step, returning the result + fn sub_one(&self) -> Self; + + /// Add an usize, returning None on overflow + fn add_usize(&self, n: usize) -> Option<Self>; +} + +// These are still macro-generated because the integer literals resolve to different types. +macro_rules! step_identical_methods { + () => { + #[inline] + fn replace_one(&mut self) -> Self { + crate::mem::replace(self, 1) + } + + #[inline] + fn replace_zero(&mut self) -> Self { + crate::mem::replace(self, 0) + } + + #[inline] + fn add_one(&self) -> Self { + Add::add(*self, 1) + } + + #[inline] + fn sub_one(&self) -> Self { + Sub::sub(*self, 1) + } + }; +} + +macro_rules! step_impl_unsigned { + ($($t:ty)*) => ($( + impl Step for $t { + fn steps_between(start: &$t, end: &$t) -> Option<usize> { + if *start < *end { + // Note: We assume $t <= usize here + Option::Some((*end - *start) as usize) + } else { + Option::Some(0) + } + } + + fn add_usize(&self, n: usize) -> Option<Self> { + match <$t>::try_from(n) { + Result::Ok(n_as_t) => self.checked_add(n_as_t), + Result::Err(_) => Option::None, + } + } + + step_identical_methods!(); + } + )*) +} +macro_rules! step_impl_signed { + ($( [$t:ty : $unsigned:ty] )*) => ($( + impl Step for $t { + #[inline] + #[allow(trivial_numeric_casts)] + fn steps_between(start: &$t, end: &$t) -> Option<usize> { + if *start < *end { + // Note: We assume $t <= isize here + // Use .wrapping_sub and cast to usize to compute the + // difference that may not fit inside the range of isize. + Option::Some((*end as isize).wrapping_sub(*start as isize) as usize) + } else { + Option::Some(0) + } + } + + #[inline] + #[allow(unreachable_patterns)] + fn add_usize(&self, n: usize) -> Option<Self> { + match <$unsigned>::try_from(n) { + Result::Ok(n_as_unsigned) => { + // Wrapping in unsigned space handles cases like + // `-120_i8.add_usize(200) == Option::Some(80_i8)`, + // even though 200_usize is out of range for i8. + let wrapped = (*self as $unsigned).wrapping_add(n_as_unsigned) as $t; + if wrapped >= *self { + Option::Some(wrapped) + } else { + Option::None // Addition overflowed + } + } + Result::Err(_) => Option::None, + } + } + + step_identical_methods!(); + } + )*) +} + +macro_rules! step_impl_no_between { + ($($t:ty)*) => ($( + impl Step for $t { + #[inline] + fn steps_between(_start: &Self, _end: &Self) -> Option<usize> { + Option::None + } + + #[inline] + fn add_usize(&self, n: usize) -> Option<Self> { + self.checked_add(n as $t) + } + + step_identical_methods!(); + } + )*) +} + +step_impl_unsigned!(usize); + +pub trait Iterator { + type Item; + + #[lang = "next"] + fn next(&mut self) -> Option<Self::Item>; +} + +impl<A: Step> Iterator for Range<A> { + type Item = A; + + fn next(&mut self) -> Option<A> { + if self.start < self.end { + // We check for overflow here, even though it can't actually + // happen. Adding this check does however help llvm vectorize loops + // for some ranges that don't get vectorized otherwise, + // and this won't actually result in an extra check in an optimized build. + match self.start.add_usize(1) { + Option::Some(mut n) => { + crate::mem::swap(&mut n, &mut self.start); + Option::Some(n) + } + Option::None => Option::None, + } + } else { + Option::None + } + } +} + +pub trait IntoIterator { + type Item; + + type IntoIter: Iterator<Item = Self::Item>; + + #[lang = "into_iter"] + fn into_iter(self) -> Self::IntoIter; +} + +impl<I: Iterator> IntoIterator for I { + type Item = I::Item; + type IntoIter = I; + + fn into_iter(self) -> I { + self + } +} + +pub fn main() { + let a = 1usize..3usize; + + for i in a { // { dg-warning "unused name" } + unsafe { puts("loop\0" as *const str as *const i8); } + } +} diff --git a/gcc/testsuite/rust/compile/for-loop2.rs b/gcc/testsuite/rust/compile/for-loop2.rs new file mode 100644 index 0000000..a0ad066 --- /dev/null +++ b/gcc/testsuite/rust/compile/for-loop2.rs @@ -0,0 +1,547 @@ +// { dg-output "1\r*\n2\r*\n" } +#![feature(intrinsics)] + +pub use option::Option::{self, None, Some}; +pub use result::Result::{self, Err, Ok}; + +extern "C" { + fn printf(s: *const i8, ...); + fn puts(s: *const i8); +} + +mod option { + pub enum Option<T> { + #[lang = "None"] + None, + #[lang = "Some"] + Some(T), + } +} + +mod result { + enum Result<T, E> { + Ok(T), + Err(E), + } +} + +#[lang = "sized"] +pub trait Sized {} + +#[lang = "clone"] +pub trait Clone: Sized { + fn clone(&self) -> Self; + + fn clone_from(&mut self, source: &Self) { + *self = source.clone() + } +} + +mod impls { + use super::Clone; + + macro_rules! impl_clone { + ($($t:ty)*) => { + $( + impl Clone for $t { + fn clone(&self) -> Self { + *self + } + } + )* + } + } + + impl_clone! { + usize u8 u16 u32 u64 // u128 + isize i8 i16 i32 i64 // i128 + f32 f64 + bool char + } +} + +#[lang = "copy"] +pub trait Copy: Clone { + // Empty. +} + +mod copy_impls { + use super::Copy; + + macro_rules! impl_copy { + ($($t:ty)*) => { + $( + impl Copy for $t {} + )* + } + } + + impl_copy! { + usize u8 u16 u32 u64 // u128 + isize i8 i16 i32 i64 // i128 + f32 f64 + bool char + } +} + +mod intrinsics { + extern "rust-intrinsic" { + pub fn add_with_overflow<T>(x: T, y: T) -> (T, bool); + pub fn wrapping_add<T>(a: T, b: T) -> T; + pub fn wrapping_sub<T>(a: T, b: T) -> T; + pub fn rotate_left<T>(a: T, b: T) -> T; + pub fn rotate_right<T>(a: T, b: T) -> T; + pub fn offset<T>(ptr: *const T, count: isize) -> *const T; + pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize); + pub fn move_val_init<T>(dst: *mut T, src: T); + pub fn uninit<T>() -> T; + } +} + +mod ptr { + #[lang = "const_ptr"] + impl<T> *const T { + pub unsafe fn offset(self, count: isize) -> *const T { + crate::intrinsics::offset(self, count) + } + } + + #[lang = "mut_ptr"] + impl<T> *mut T { + pub unsafe fn offset(self, count: isize) -> *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 = 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 crate::mem::size_of::<T>() < 32 { + let z = read(x); + crate::intrinsics::copy_nonoverlapping(y, x, 1); + write(y, z); + } else { + swap_nonoverlapping(x, y, 1); + } + } + + pub unsafe fn write<T>(dst: *mut T, src: T) { + crate::intrinsics::move_val_init(&mut *dst, src) + } + + pub unsafe fn read<T>(src: *const T) -> T { + let mut tmp: T = crate::mem::uninitialized(); + crate::intrinsics::copy_nonoverlapping(src, &mut tmp, 1); + tmp + } + + pub unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) { + struct Block(u64, u64, u64, u64); + struct UnalignedBlock(u64, u64, u64, u64); + + 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 + // N.B. We can't use a for loop as the `range` impl calls `mem::swap` recursively + let mut i: usize = 0; + 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 = 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 + 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 = 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); + + crate::intrinsics::copy_nonoverlapping(x, t, rem); + crate::intrinsics::copy_nonoverlapping(y, x, rem); + crate::intrinsics::copy_nonoverlapping(t, y, rem); + } + } +} + +mod mem { + extern "rust-intrinsic" { + #[rustc_const_stable(feature = "const_transmute", since = "1.46.0")] + pub fn transmute<T, U>(_: T) -> U; + #[rustc_const_stable(feature = "const_size_of", since = "1.40.0")] + pub fn size_of<T>() -> usize; + } + + pub fn swap<T>(x: &mut T, y: &mut T) { + unsafe { + crate::ptr::swap_nonoverlapping_one(x, y); + } + } + + pub fn replace<T>(dest: &mut T, mut src: T) -> T { + swap(dest, &mut src); + src + } + + pub unsafe fn uninitialized<T>() -> T { + crate::intrinsics::uninit() + } +} + +macro_rules! impl_uint { + ($($ty:ident = $lang:literal),*) => { + $( + impl $ty { + pub fn wrapping_add(self, rhs: Self) -> Self { + unsafe { + crate::intrinsics::wrapping_add(self, rhs) + } + } + + pub fn wrapping_sub(self, rhs: Self) -> Self { + unsafe { + crate::intrinsics::wrapping_sub(self, rhs) + } + } + + pub fn rotate_left(self, n: u32) -> Self { + unsafe { + crate::intrinsics::rotate_left(self, n as Self) + } + } + + pub fn rotate_right(self, n: u32) -> Self { + unsafe { + crate::intrinsics::rotate_right(self, n as Self) + } + } + + pub fn to_le(self) -> Self { + #[cfg(target_endian = "little")] + { + self + } + } + + pub const fn from_le_bytes(bytes: [u8; crate::mem::size_of::<Self>()]) -> Self { + Self::from_le(Self::from_ne_bytes(bytes)) + } + + pub const fn from_le(x: Self) -> Self { + #[cfg(target_endian = "little")] + { + x + } + } + + pub const fn from_ne_bytes(bytes: [u8; crate::mem::size_of::<Self>()]) -> Self { + unsafe { crate::mem::transmute(bytes) } + } + + pub fn checked_add(self, rhs: Self) -> Option<Self> { + let (a, b) = self.overflowing_add(rhs); + if b { + Option::None + } else { + Option::Some(a) + } + } + + pub fn overflowing_add(self, rhs: Self) -> (Self, bool) { + let (a, b) = unsafe { crate::intrinsics::add_with_overflow(self as $ty, rhs as $ty) }; + (a as Self, b) + } + } + )* + } +} + +impl_uint!( + u8 = "u8", + u16 = "u16", + u32 = "u32", + u64 = "u64", + usize = "usize" +); + +#[lang = "add"] +pub 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; + + fn add(self, other: $t) -> $t { self + other } + } + )*) +} + +add_impl! { usize u8 u16 u32 u64 /*isize i8 i16 i32 i64*/ f32 f64 } + +#[lang = "sub"] +pub trait Sub<RHS = Self> { + type Output; + + fn sub(self, rhs: RHS) -> Self::Output; +} +macro_rules! sub_impl { + ($($t:ty)*) => ($( + impl Sub for $t { + type Output = $t; + + fn sub(self, other: $t) -> $t { self - other } + } + )*) +} + +sub_impl! { usize u8 u16 u32 u64 /*isize i8 i16 i32 i64*/ f32 f64 } + +#[lang = "Range"] +pub struct Range<Idx> { + pub start: Idx, + pub end: Idx, +} + +pub trait TryFrom<T>: Sized { + /// The type returned in the event of a conversion error. + type Error; + + /// Performs the conversion. + fn try_from(value: T) -> Result<Self, Self::Error>; +} + +pub trait From<T>: Sized { + fn from(_: T) -> Self; +} + +impl<T> From<T> for T { + fn from(t: T) -> T { + t + } +} + +impl<T, U> TryFrom<U> for T +where + T: From<U>, +{ + type Error = !; + + fn try_from(value: U) -> Result<Self, Self::Error> { + Ok(T::from(value)) + } +} + +trait Step { + /// Returns the number of steps between two step objects. The count is + /// inclusive of `start` and exclusive of `end`. + /// + /// Returns `None` if it is not possible to calculate `steps_between` + /// without overflow. + fn steps_between(start: &Self, end: &Self) -> Option<usize>; + + /// Replaces this step with `1`, returning itself + fn replace_one(&mut self) -> Self; + + /// Replaces this step with `0`, returning itself + fn replace_zero(&mut self) -> Self; + + /// Adds one to this step, returning the result + fn add_one(&self) -> Self; + + /// Subtracts one to this step, returning the result + fn sub_one(&self) -> Self; + + /// Add an usize, returning None on overflow + fn add_usize(&self, n: usize) -> Option<Self>; +} + +// These are still macro-generated because the integer literals resolve to different types. +macro_rules! step_identical_methods { + () => { + #[inline] + fn replace_one(&mut self) -> Self { + crate::mem::replace(self, 1) + } + + #[inline] + fn replace_zero(&mut self) -> Self { + crate::mem::replace(self, 0) + } + + #[inline] + fn add_one(&self) -> Self { + Add::add(*self, 1) + } + + #[inline] + fn sub_one(&self) -> Self { + Sub::sub(*self, 1) + } + }; +} + +macro_rules! step_impl_unsigned { + ($($t:ty)*) => ($( + impl Step for $t { + fn steps_between(start: &$t, end: &$t) -> Option<usize> { + if *start < *end { + // Note: We assume $t <= usize here + Option::Some((*end - *start) as usize) + } else { + Option::Some(0) + } + } + + fn add_usize(&self, n: usize) -> Option<Self> { + match <$t>::try_from(n) { + Result::Ok(n_as_t) => self.checked_add(n_as_t), + Result::Err(_) => Option::None, + } + } + + step_identical_methods!(); + } + )*) +} +macro_rules! step_impl_signed { + ($( [$t:ty : $unsigned:ty] )*) => ($( + impl Step for $t { + #[inline] + #[allow(trivial_numeric_casts)] + fn steps_between(start: &$t, end: &$t) -> Option<usize> { + if *start < *end { + // Note: We assume $t <= isize here + // Use .wrapping_sub and cast to usize to compute the + // difference that may not fit inside the range of isize. + Option::Some((*end as isize).wrapping_sub(*start as isize) as usize) + } else { + Option::Some(0) + } + } + + #[inline] + #[allow(unreachable_patterns)] + fn add_usize(&self, n: usize) -> Option<Self> { + match <$unsigned>::try_from(n) { + Result::Ok(n_as_unsigned) => { + // Wrapping in unsigned space handles cases like + // `-120_i8.add_usize(200) == Option::Some(80_i8)`, + // even though 200_usize is out of range for i8. + let wrapped = (*self as $unsigned).wrapping_add(n_as_unsigned) as $t; + if wrapped >= *self { + Option::Some(wrapped) + } else { + Option::None // Addition overflowed + } + } + Result::Err(_) => Option::None, + } + } + + step_identical_methods!(); + } + )*) +} + +macro_rules! step_impl_no_between { + ($($t:ty)*) => ($( + impl Step for $t { + #[inline] + fn steps_between(_start: &Self, _end: &Self) -> Option<usize> { + Option::None + } + + #[inline] + fn add_usize(&self, n: usize) -> Option<Self> { + self.checked_add(n as $t) + } + + step_identical_methods!(); + } + )*) +} + +step_impl_unsigned!(usize); + +pub trait Iterator { + type Item; + + #[lang = "next"] + fn next(&mut self) -> Option<Self::Item>; +} + +impl<A: Step> Iterator for Range<A> { + type Item = A; + + fn next(&mut self) -> Option<A> { + if self.start < self.end { + // We check for overflow here, even though it can't actually + // happen. Adding this check does however help llvm vectorize loops + // for some ranges that don't get vectorized otherwise, + // and this won't actually result in an extra check in an optimized build. + match self.start.add_usize(1) { + Option::Some(mut n) => { + crate::mem::swap(&mut n, &mut self.start); + Option::Some(n) + } + Option::None => Option::None, + } + } else { + Option::None + } + } +} + +pub trait IntoIterator { + type Item; + + type IntoIter: Iterator<Item = Self::Item>; + + #[lang = "into_iter"] + fn into_iter(self) -> Self::IntoIter; +} + +impl<I: Iterator> IntoIterator for I { + type Item = I::Item; + type IntoIter = I; + + fn into_iter(self) -> I { + self + } +} + +pub fn main() { + // make sure we can desugar for-loops inside other blocks + + if true { + for _ in 20usize..40usize { + unsafe { + puts("loop\0" as *const str as *const i8); + } + } + } +} diff --git a/gcc/testsuite/rust/compile/format_args_extra_comma.rs b/gcc/testsuite/rust/compile/format_args_extra_comma.rs new file mode 100644 index 0000000..fcc435c --- /dev/null +++ b/gcc/testsuite/rust/compile/format_args_extra_comma.rs @@ -0,0 +1,47 @@ +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +macro_rules! format_args { + () => {}; +} + +#[lang = "sized"] +trait Sized {} + +pub mod core { + pub mod fmt { + pub struct Formatter; + pub struct Result; + + pub struct Arguments<'a>; + + impl<'a> Arguments<'a> { + pub fn new_v1(_: &'a [&'static str], _: &'a [ArgumentV1<'a>]) -> Arguments<'a> { + Arguments + } + } + + pub struct ArgumentV1<'a>; + + impl<'a> ArgumentV1<'a> { + pub fn new<'b, T>(_: &'b T, _: fn(&T, &mut Formatter) -> Result) -> ArgumentV1 { + ArgumentV1 + } + } + + pub trait Display { + fn fmt(&self, _: &mut Formatter) -> Result; + } + + impl Display for i32 { + fn fmt(&self, _: &mut Formatter) -> Result { + // { dg-warning "unused name .self." "" { target *-*-* } .-1 } + Result + } + } + } +} + +fn main() { + let _formatted = format_args!("extra commas {} {}", 15, 14,); +} diff --git a/gcc/testsuite/rust/compile/functions_without_body.rs b/gcc/testsuite/rust/compile/functions_without_body.rs index 36ddea5..0a0e602 100644 --- a/gcc/testsuite/rust/compile/functions_without_body.rs +++ b/gcc/testsuite/rust/compile/functions_without_body.rs @@ -1,3 +1,4 @@ +// { dg-additional-options "-frust-compile-until=nameresolution" } struct MyStruct; trait X {} diff --git a/gcc/testsuite/rust/compile/generic-default1.rs b/gcc/testsuite/rust/compile/generic-default1.rs index 0a132bf..4155640 100644 --- a/gcc/testsuite/rust/compile/generic-default1.rs +++ b/gcc/testsuite/rust/compile/generic-default1.rs @@ -1,5 +1,5 @@ struct Foo<A = i321>(A); -// { dg-error "failed to resolve TypePath: i321" "" { target *-*-* } .-1 } +// { dg-error "could not resolve type path .i321." "" { target *-*-* } .-1 } fn main() { let a; diff --git a/gcc/testsuite/rust/compile/generic_auto_trait.rs b/gcc/testsuite/rust/compile/generic_auto_trait.rs index ae6a51d..a0a414c 100644 --- a/gcc/testsuite/rust/compile/generic_auto_trait.rs +++ b/gcc/testsuite/rust/compile/generic_auto_trait.rs @@ -1,2 +1,3 @@ +#![feature(optin_builtin_traits)] auto trait IsCooler<G> {} // { dg-error "auto traits cannot have generic parameters .E0567." "" { target *-*-* } .-1 } diff --git a/gcc/testsuite/rust/compile/generics4.rs b/gcc/testsuite/rust/compile/generics4.rs index 31b681a..c4dbc43 100644 --- a/gcc/testsuite/rust/compile/generics4.rs +++ b/gcc/testsuite/rust/compile/generics4.rs @@ -6,7 +6,6 @@ struct GenericStruct<T>(T, usize); fn main() { let a2; a2 = GenericStruct::<i8, i32>(1, 456); // { dg-error "generic item takes at most 1 type arguments but 2 were supplied" } - // { dg-error {Failed to resolve expression of function call} "" { target *-*-* } .-1 } let b2: i32 = a2.0; // { dg-error {Expected Tuple or ADT got: T\?} "" { target *-*-* } .-1 } diff --git a/gcc/testsuite/rust/compile/generics5.rs b/gcc/testsuite/rust/compile/generics5.rs index 6c847b5..f861038 100644 --- a/gcc/testsuite/rust/compile/generics5.rs +++ b/gcc/testsuite/rust/compile/generics5.rs @@ -3,7 +3,7 @@ struct GenericStruct<T>(T, usize); fn main() { let a2; a2 = GenericStruct::<i8, T>(1, 456); - // { dg-error "failed to resolve TypePath: T" "" { target *-*-* } .-1 } + // { dg-error "could not resolve type path .T." "" { target *-*-* } .-1 } let b2: i32 = a2.0; let c2: usize = a2.1; diff --git a/gcc/testsuite/rust/compile/generics6.rs b/gcc/testsuite/rust/compile/generics6.rs index 33093cf..d77c559 100644 --- a/gcc/testsuite/rust/compile/generics6.rs +++ b/gcc/testsuite/rust/compile/generics6.rs @@ -27,6 +27,5 @@ impl Foo<f32> { fn main() { let a: i32 = Foo::test(); // { dg-error "multiple applicable items in scope for: .test." } - // { dg-error {Failed to resolve expression of function call} "" { target *-*-* } .-1 } } diff --git a/gcc/testsuite/rust/compile/generics9.rs b/gcc/testsuite/rust/compile/generics9.rs index 3766703..56c6198 100644 --- a/gcc/testsuite/rust/compile/generics9.rs +++ b/gcc/testsuite/rust/compile/generics9.rs @@ -1,5 +1,6 @@ +// { dg-additional-options "-frust-name-resolution-2.0" } struct Foo<A, B = (A, B)>(A, B); -// { dg-error "failed to resolve TypePath: B" "" { target *-*-* } .-1 } +// { dg-error "type parameters with a default cannot use forward declared identifiers" "" { target *-*-* } .-1 } fn main() { let a: Foo<bool>; diff --git a/gcc/testsuite/rust/compile/if-without-else.rs b/gcc/testsuite/rust/compile/if-without-else.rs new file mode 100644 index 0000000..1a0f644 --- /dev/null +++ b/gcc/testsuite/rust/compile/if-without-else.rs @@ -0,0 +1,9 @@ +fn foo(pred: bool) -> u8 { + if pred { // { dg-error "mismatched types" } + 1 + } + 3 +} + +fn main(){ +} diff --git a/gcc/testsuite/rust/compile/if_let_expr.rs b/gcc/testsuite/rust/compile/if_let_expr.rs index 7bab19a..b0879e5 100644 --- a/gcc/testsuite/rust/compile/if_let_expr.rs +++ b/gcc/testsuite/rust/compile/if_let_expr.rs @@ -7,8 +7,9 @@ pub enum Option<T> { } fn main() { - let x = Option::Some(3); // { dg-warning "unused name" } - let a = if let Option::Some(1) = x { + let x = Option::Some(3); + + let a = if let Option::Some(1) = x {// { dg-warning "unused name" } 1 } else if x == Option::Some(2) { 2 diff --git a/gcc/testsuite/rust/compile/if_let_expr_simple.rs b/gcc/testsuite/rust/compile/if_let_expr_simple.rs new file mode 100644 index 0000000..d7fb0af --- /dev/null +++ b/gcc/testsuite/rust/compile/if_let_expr_simple.rs @@ -0,0 +1,12 @@ +enum MyOption { + Some(i32), + None, +} + +pub fn toto(i : MyOption) -> i32 { + if let MyOption::Some(v) = i { + v + } else { + 23i32 + } +} diff --git a/gcc/testsuite/rust/compile/iflet.rs b/gcc/testsuite/rust/compile/iflet.rs new file mode 100644 index 0000000..6d46339 --- /dev/null +++ b/gcc/testsuite/rust/compile/iflet.rs @@ -0,0 +1,32 @@ +pub fn simple_iflet() -> i32 { + let mut res = 0; + + enum E { + X(i32), + } + let v = E::X(4); + + if let E::X(n) = v { + res = 1; + } + + res +} + +pub fn simple_iflet_else() -> i32 { + let mut res = 0; + + enum E { + X(i32), + Y, + } + let v = E::X(4); + + if let E::Y = v { + res = 1; + } else { + res = 2; + } + + res +} diff --git a/gcc/testsuite/rust/compile/implicit_returns_err3.rs b/gcc/testsuite/rust/compile/implicit_returns_err3.rs index ac98213..f0330ac 100644 --- a/gcc/testsuite/rust/compile/implicit_returns_err3.rs +++ b/gcc/testsuite/rust/compile/implicit_returns_err3.rs @@ -1,6 +1,6 @@ fn test(x: i32) -> i32 { // { dg-error "mismatched types, expected .i32. but got ...." } if x > 1 { - 1 + return 1; } } diff --git a/gcc/testsuite/rust/compile/inline_asm_compile_nop.rs b/gcc/testsuite/rust/compile/inline_asm_compile_nop.rs new file mode 100644 index 0000000..c49667c --- /dev/null +++ b/gcc/testsuite/rust/compile/inline_asm_compile_nop.rs @@ -0,0 +1,12 @@ +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +macro_rules! asm { + () => {} +} + +fn main() { + unsafe { + asm!("nop"); + } +}
\ No newline at end of file diff --git a/gcc/testsuite/rust/compile/inline_asm_illegal_operands.rs b/gcc/testsuite/rust/compile/inline_asm_illegal_operands.rs index 5a13fb9..f29b4b6 100644 --- a/gcc/testsuite/rust/compile/inline_asm_illegal_operands.rs +++ b/gcc/testsuite/rust/compile/inline_asm_illegal_operands.rs @@ -11,14 +11,14 @@ fn main() { asm!( "add {x}, {1}", x = in(reg) _x, - x = in(reg) _x, // { dg-error {duplicate argument named 'x'} "" { xfail *-*-* } .-1 } + x = in(reg) _x, // { dg-error {duplicate argument named 'x'} } ); asm!( "mov {x}, {x}", - x = inout("eax") _x, // { dg-error {explicit register arguments cannot have names} "" { xfail *-*-* } .-1 } + x = inout("eax") _x, // { dg-error {explicit register arguments cannot have names} } x = inout(reg) _x, // It then proceeds to parse this line, resulting in only 1 error instead of duplication error as well. ); } _x = 1; -}
\ No newline at end of file +} diff --git a/gcc/testsuite/rust/compile/inline_asm_parse_operand.rs b/gcc/testsuite/rust/compile/inline_asm_parse_operand.rs index 2770263..c7bc152 100644 --- a/gcc/testsuite/rust/compile/inline_asm_parse_operand.rs +++ b/gcc/testsuite/rust/compile/inline_asm_parse_operand.rs @@ -2,13 +2,13 @@ #[rustc_builtin_macro] macro_rules! asm { - () => {} + () => {}; } -fn main() { +fn main() -> i32 { unsafe { asm!( - "add {0:e}, {0:e}", + "add {}, 1", in(reg) 0 ); } @@ -20,18 +20,20 @@ fn main() { let _num2: i32 = 20; unsafe { asm!( - "add {0}, {0}", - inout(reg) num1 =>_num1, + "add {}, {}", in(reg) _num2, + out(reg) _num1, ); } - let mut _output_testing : u32 = 0; + let mut _output_testing: u32 = 0; unsafe { asm!( - "add {0}, {0}", + "add {}, 1", in(reg) _num1, - out(reg) _, + //out(reg) _, ); } -}
\ No newline at end of file + + 0 +} diff --git a/gcc/testsuite/rust/compile/inline_asm_parse_output_operand.rs b/gcc/testsuite/rust/compile/inline_asm_parse_output_operand.rs new file mode 100644 index 0000000..a67fff5 --- /dev/null +++ b/gcc/testsuite/rust/compile/inline_asm_parse_output_operand.rs @@ -0,0 +1,18 @@ +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +fn main() { + let mut _num1: i32 = 10; + let mut _num2: i32 = 10; + unsafe { + asm!( + "mov {}, 4", + out(reg) _num1, + out(reg) _num2, + ); + } +} diff --git a/gcc/testsuite/rust/compile/inline_asm_typecheck.rs b/gcc/testsuite/rust/compile/inline_asm_typecheck.rs new file mode 100644 index 0000000..b2daefc --- /dev/null +++ b/gcc/testsuite/rust/compile/inline_asm_typecheck.rs @@ -0,0 +1,20 @@ +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +fn main() { + let mut _num1: i32 = 10; + let mut _num2: i32 = 10; + unsafe { + // This demonstrates that asm!'s is inferred with a unit type is parsed correctly. + let _ = asm!("nop"); + + // The asm! block never returns, and its return type is defined as ! (never). + // Behavior is undefined if execution falls through past the end of the asm code. + // A noreturn asm block behaves just like a function which doesn't return; notably, local variables in scope are not dropped before it is invoked. + let _ = asm!("nop", options(noreturn)); + } +} diff --git a/gcc/testsuite/rust/compile/invalid_label_name.rs b/gcc/testsuite/rust/compile/invalid_label_name.rs index 5c850da..66e40a6 100644 --- a/gcc/testsuite/rust/compile/invalid_label_name.rs +++ b/gcc/testsuite/rust/compile/invalid_label_name.rs @@ -1,20 +1,24 @@ +// { dg-additional-options "-frust-name-resolution-2.0" } pub fn function() { 'continue: loop { // { dg-error "invalid label name .'continue." "" { target *-*-* } .-1 } break 'extern; // { dg-error "invalid label name .'extern." "" { target *-*-* } .-1 } + // { dg-error "use of undeclared label .'extern." "" { target *-*-* } .-2 } } 'break: loop { // { dg-error "invalid label name .'break." "" { target *-*-* } .-1 } break 'for; // { dg-error "invalid label name .'for." "" { target *-*-* } .-1 } + // { dg-error "use of undeclared label .'for." "" { target *-*-* } .-2 } } 'crate: loop { // { dg-error "invalid label name .'crate." "" { target *-*-* } .-1 } break 'loop; // { dg-error "invalid label name .'loop." "" { target *-*-* } .-1 } + // { dg-error "use of undeclared label .'loop." "" { target *-*-* } .-2 } } 'a: loop { diff --git a/gcc/testsuite/rust/compile/issue-1446.rs b/gcc/testsuite/rust/compile/issue-1446.rs index 8bfa42b..969ad38 100644 --- a/gcc/testsuite/rust/compile/issue-1446.rs +++ b/gcc/testsuite/rust/compile/issue-1446.rs @@ -1,3 +1,11 @@ +// fake function +pub fn swap_bytes(this: u32) -> u32 { + (((this) & 0xff000000) >> 24) + | (((this) & 0x00ff0000) >> 8) + | (((this) & 0x0000ff00) << 8) + | (((this) & 0x000000ff) << 24) +} + pub fn to_le(this: u32) -> u32 { #[cfg(target_endian = "little")] { @@ -5,6 +13,6 @@ pub fn to_le(this: u32) -> u32 { } #[cfg(not(target_endian = "little"))] { - this.swap_bytes() + swap_bytes(this) } } diff --git a/gcc/testsuite/rust/compile/issue-1525.rs b/gcc/testsuite/rust/compile/issue-1525.rs new file mode 100644 index 0000000..b2247cd --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-1525.rs @@ -0,0 +1,4 @@ +fn main() { + const slice: &[i32] = &[1, 2, 3]; + let _slice2: &[i32] = slice; +} diff --git a/gcc/testsuite/rust/compile/issue-1773.rs b/gcc/testsuite/rust/compile/issue-1773.rs index 468497a..41c82f0 100644 --- a/gcc/testsuite/rust/compile/issue-1773.rs +++ b/gcc/testsuite/rust/compile/issue-1773.rs @@ -1,8 +1,4 @@ -#[lang = "sized"] -// { dg-skip-if "" { *-*-* } } -pub trait Sized {} - -trait Foo<T> { +trait Foo { type A; fn test(a: Self::A) -> Self::A { @@ -10,9 +6,14 @@ trait Foo<T> { } } -struct Bar<T>(T); -impl<T> Foo<T> for Bar<i32> { - type A = T; +struct Bar(i32); +impl Foo for Bar { + type A = i32; +} + +struct Baz(f32); +impl Foo for Baz { + type A = f32; } fn main() { @@ -21,4 +22,10 @@ fn main() { let b; b = Bar::test(a.0); + + let c; + c = Baz(123f32); + + let d; + d = Baz::test(c.0); } diff --git a/gcc/testsuite/rust/compile/issue-1901.rs b/gcc/testsuite/rust/compile/issue-1901.rs index dd41ff8..b43e34f 100644 --- a/gcc/testsuite/rust/compile/issue-1901.rs +++ b/gcc/testsuite/rust/compile/issue-1901.rs @@ -1,3 +1,5 @@ +#![feature(intrinsics)] + #[lang = "sized"] pub trait Sized {} @@ -11,14 +13,14 @@ 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 } } } diff --git a/gcc/testsuite/rust/compile/issue-1981.rs b/gcc/testsuite/rust/compile/issue-1981.rs index b1637ac..de9588c 100644 --- a/gcc/testsuite/rust/compile/issue-1981.rs +++ b/gcc/testsuite/rust/compile/issue-1981.rs @@ -1,3 +1,5 @@ +#![feature(intrinsics)] + #[lang = "sized"] pub trait Sized {} @@ -14,30 +16,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); @@ -45,12 +47,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 } @@ -58,7 +60,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 @@ -67,31 +69,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); } } } @@ -104,7 +106,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); } } @@ -114,7 +116,7 @@ mod mem { } pub unsafe fn uninitialized<T>() -> T { - intrinsics::uninit() + crate::intrinsics::uninit() } } @@ -124,7 +126,7 @@ trait Step { impl Step for i32 { fn replace_zero(&mut self) -> Self { - mem::replace(self, 0) + crate::mem::replace(self, 0) } } diff --git a/gcc/testsuite/rust/compile/issue-2015.rs b/gcc/testsuite/rust/compile/issue-2015.rs new file mode 100644 index 0000000..7789ecd --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2015.rs @@ -0,0 +1,19 @@ +// { dg-additional-options "-frust-compile-until=lowering" } + +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-2035.rs b/gcc/testsuite/rust/compile/issue-2035.rs new file mode 100644 index 0000000..c0817d5 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2035.rs @@ -0,0 +1,10 @@ +fn func(i: i32) { + i(); + // { dg-error "expected function, found .i32. .E0618." "" { target *-*-* } .-1 } +} + +fn main() { + let i = 0i32; + i(); + // { dg-error "expected function, found .i32. .E0618." "" { target *-*-* } .-1 } +} diff --git a/gcc/testsuite/rust/compile/issue-2203.rs b/gcc/testsuite/rust/compile/issue-2203.rs new file mode 100644 index 0000000..961381d --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2203.rs @@ -0,0 +1,3 @@ +trait A {} + +impl A for () {} diff --git a/gcc/testsuite/rust/compile/issue-2323.rs b/gcc/testsuite/rust/compile/issue-2323.rs new file mode 100644 index 0000000..02a3f90 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2323.rs @@ -0,0 +1,9 @@ +#[lang = "sized"] +trait Sized {} + +pub struct S<T>(T); + +pub fn foo<T>(x: T) { + let y = S(x); + y.0; +} diff --git a/gcc/testsuite/rust/compile/issue-2324-1.rs b/gcc/testsuite/rust/compile/issue-2324-1.rs new file mode 100644 index 0000000..afce1f3 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2324-1.rs @@ -0,0 +1,19 @@ +enum State { + Succeeded, + Failed(u32), +} + +fn print_on_failure(state: &State) { + match *state { + State::Succeeded => (), + State::Failed => (), // { dg-error "expected unit struct, unit variant or constant, found tuple variant" } + _ => () + } +} + +fn main() { + let b = State::Failed(1); + + print_on_failure(&b); + +} diff --git a/gcc/testsuite/rust/compile/issue-2324-2.rs b/gcc/testsuite/rust/compile/issue-2324-2.rs new file mode 100644 index 0000000..1530b00 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2324-2.rs @@ -0,0 +1,19 @@ +enum State { + Succeeded, + Failed { x: u32 }, +} + +fn print_on_failure(state: &State) { + match *state { + State::Succeeded => (), + State::Failed => (), // { dg-error "expected unit struct, unit variant or constant, found struct variant" } + _ => () + } +} + +fn main() { + let b = State::Failed{x: 1}; + + print_on_failure(&b); + +} diff --git a/gcc/testsuite/rust/compile/issue-2330.rs b/gcc/testsuite/rust/compile/issue-2330.rs index 97c1503..6ab46c7 100644 --- a/gcc/testsuite/rust/compile/issue-2330.rs +++ b/gcc/testsuite/rust/compile/issue-2330.rs @@ -95,30 +95,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); @@ -126,12 +126,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 } @@ -139,7 +139,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 @@ -148,31 +148,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); } } } @@ -185,7 +185,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); } } @@ -195,6 +195,6 @@ mod mem { } pub unsafe fn uninitialized<T>() -> T { - intrinsics::uninit() + crate::intrinsics::uninit() } } diff --git a/gcc/testsuite/rust/compile/issue-2369.rs b/gcc/testsuite/rust/compile/issue-2369.rs new file mode 100644 index 0000000..9475aef --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2369.rs @@ -0,0 +1,21 @@ +#[lang = "sized"] +trait Sized {} + +fn main() { + pub trait Foo { + type A; + fn boo(&self) -> <Self as Foo>::A; + } + + struct Bar; + + impl Foo for isize { + type A = usize; + fn boo(&self) -> usize { + 42 + } + } + + fn baz<I>(x: &<I as Foo<A = Bar>>::A) {} + // { dg-error "associated type bindings are not allowed here .E0229." "" { target *-*-* } .-1 } +} diff --git a/gcc/testsuite/rust/compile/issue-2394.rs b/gcc/testsuite/rust/compile/issue-2394.rs new file mode 100644 index 0000000..92f7afc --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2394.rs @@ -0,0 +1,14 @@ +const A: i32 = (1 / 0); +// { dg-error "division by zero" "" { target *-*-* } .-1 } + +fn main() { + let a = 1 / 0; + // { dg-error "division by zero" "" { target *-*-* } .-1 } + + let b = 3; + let c = b / 0; + // { dg-error "division by zero" "" { target *-*-* } .-1 } + + let a = 1 << 500; + // { dg-error "left shift count >= width of type" "" { target *-*-* } .-1 } +} diff --git a/gcc/testsuite/rust/compile/issue-2423.rs b/gcc/testsuite/rust/compile/issue-2423.rs new file mode 100644 index 0000000..6fcd32f --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2423.rs @@ -0,0 +1,14 @@ +impl NonExistant { + // { dg-error "could not resolve" "" { target *-*-* } .-1 } + fn test() {} +} + +impl NotFound for NonExistant { + // { dg-error "could not resolve" "" { target *-*-* } .-1 } + fn test() {} +} + +trait A {} + +impl A for NotFound {} +// { dg-error "could not resolve" "" { target *-*-* } .-1 } diff --git a/gcc/testsuite/rust/compile/issue-2499.rs b/gcc/testsuite/rust/compile/issue-2499.rs new file mode 100644 index 0000000..662d58f --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2499.rs @@ -0,0 +1,11 @@ +#[lang = "sized"] +pub trait Sized {} + +struct Foo; +struct Bar; + +impl Foo for Bar {} +// { dg-error "Expected a trait found .Foo. .E0404." "" { target *-*-* } .-1 } + +fn baz<T: Foo>(t: T) {} +// { dg-error "Expected a trait found .Foo. .E0404." "" { target *-*-* } .-1 } diff --git a/gcc/testsuite/rust/compile/issue-2567-1.rs b/gcc/testsuite/rust/compile/issue-2567-1.rs new file mode 100644 index 0000000..f5af249 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2567-1.rs @@ -0,0 +1,8 @@ +// { dg-options "-w" } +enum Empty {} + +fn foo(x: Empty) { + let x: Empty = match x { + // empty + }; +} diff --git a/gcc/testsuite/rust/compile/issue-2567-2.rs b/gcc/testsuite/rust/compile/issue-2567-2.rs new file mode 100644 index 0000000..719511d --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2567-2.rs @@ -0,0 +1,8 @@ +// { dg-options "-w" } +enum Empty {} + +fn foo(x: Empty) { + let x: i32 = match x { + // empty + }; +} diff --git a/gcc/testsuite/rust/compile/issue-2567-3.rs b/gcc/testsuite/rust/compile/issue-2567-3.rs new file mode 100644 index 0000000..09efaf0 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2567-3.rs @@ -0,0 +1,8 @@ +// { dg-options "-w" } +enum Empty {} + +fn foo(x: Empty) { + match x { + // empty + } +} diff --git a/gcc/testsuite/rust/compile/issue-266.rs b/gcc/testsuite/rust/compile/issue-266.rs new file mode 100644 index 0000000..11196cb --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-266.rs @@ -0,0 +1,3 @@ +fn main() { + 'label: while break 'label {} +} diff --git a/gcc/testsuite/rust/compile/issue-2812.rs b/gcc/testsuite/rust/compile/issue-2812.rs index 173259b..0de1738 100644 --- a/gcc/testsuite/rust/compile/issue-2812.rs +++ b/gcc/testsuite/rust/compile/issue-2812.rs @@ -1,4 +1,4 @@ // { dg-additional-options "-frust-compile-until=astvalidation" } fn foo_1(&self); -fn foo_1(&mut self); -fn foo_1(self); +fn foo_2(&mut self); +fn foo_3(self); diff --git a/gcc/testsuite/rust/compile/issue-2847.rs b/gcc/testsuite/rust/compile/issue-2847.rs new file mode 100644 index 0000000..2bc5566 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2847.rs @@ -0,0 +1,8 @@ +pub fn myfun1((x, _): (i32, i32)) -> i32 { + x +} + +pub fn myfun2() -> i32 { + let (x, _) = (1, 2); + x +} diff --git a/gcc/testsuite/rust/compile/issue-2905-1.rs b/gcc/testsuite/rust/compile/issue-2905-1.rs new file mode 100644 index 0000000..9b0c19d --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2905-1.rs @@ -0,0 +1,27 @@ +#![feature(lang_items)] + +#[lang = "sized"] +trait Sized {} + +pub struct A<T>(T); + +pub trait B { + type C; +} + +// ------ +// swap these two items + +impl B for i32 { + type C = Weird<i32>; +} + +pub struct Weird<T>(A<(T,)>); + +// ------ + +trait Foo {} + +impl Foo for Weird<i32> {} + +fn main() {} diff --git a/gcc/testsuite/rust/compile/issue-2905-2.rs b/gcc/testsuite/rust/compile/issue-2905-2.rs new file mode 100644 index 0000000..1c9516d --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2905-2.rs @@ -0,0 +1,136 @@ +// { dg-options "-w" } +#![feature(intrinsics)] +#![feature(lang_items)] + +#[lang = "sized"] +trait Sized {} + +extern "rust-intrinsic" { + fn transmute<T, U>(_: T) -> U; + fn offset<T>(src: *const T, offset: isize) -> *const T; +} + +pub mod core { + pub mod marker { + #[lang = "phantom_data"] + pub struct PhantomData<T>; + } + + pub mod slice { + use crate::core::marker::PhantomData; + use crate::core::option::Option; + + impl<T> crate::core::iter::IntoIterator for &[T] { + type Item = &T; + type IntoIter = Weird<T>; + + fn into_iter(self) -> Weird<T> { + self.iter() + } + } + + pub struct Weird<T> { + ptr: *const T, // should be NonNull<T> but here it does not matter + end: *const T, + _marker: PhantomData<&T>, + } + + impl<T> Weird<T> { + pub(super) fn new(slice: &[T]) -> Self { + let ptr = slice.as_ptr(); + // SAFETY: Similar to `IterMut::new`. + unsafe { + // should be: ptr.add(slice.len()) + let end = transmute::<*const T, usize>(ptr) + slice.len(); // TODO(Arthur): Missing `* size_of::<T>()`? + let end = transmute::<usize, *const T>(end); + + Self { + ptr, + end, + _marker: PhantomData, + } + } + } + + fn is_empty(&self) -> bool { + self.ptr == self.end + } + + fn next_unchecked(&mut self) -> *const T { + let old = self.ptr; + + self.ptr = unsafe { offset(self.ptr, 1) }; + + old + } + } + + trait Foo {} + + impl<T> Foo for Weird<T> {} + + // impl<T> core::iter::Iterator for Iter<T> { + // type Item = &T; + + // fn next(&mut self) -> Option<&T> { + // if self.is_empty() { + // Option::None + // } else { + // Option::Some(&*self.next_unchecked()) + // } + // } + // } + + union Repr<T> { + pub(crate) rust: *const [T], + rust_mut: *mut [T], + pub(crate) raw: FatPtr<T>, + } + + struct FatPtr<T> { + data: *const T, + pub(crate) len: usize, + } + + impl<T> [T] { + pub fn iter(&self) -> Weird<T> { + Weird::new(self) + } + + pub fn as_ptr(&self) -> *const T { + self as *const [T] as *const T + } + + pub fn len(&self) -> usize { + unsafe { Repr { rust: self }.raw.len } + } + } + } + + pub mod iter { + use crate::core::option::Option; + + pub trait IntoIterator { + type Item; + + type IntoIter: Iterator<Item = Self::Item>; + + fn into_iter(self) -> Self::IntoIter; + } + + pub trait Iterator { + type Item; + + fn next(&mut self) -> Option<Self::Item>; + } + } + + pub mod option { + pub enum Option<T> { + Some(T), + None, + } + } +} + +fn main() {} diff --git a/gcc/testsuite/rust/compile/issue-2907.rs b/gcc/testsuite/rust/compile/issue-2907.rs new file mode 100644 index 0000000..1af843f --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2907.rs @@ -0,0 +1,33 @@ +#![feature(lang_items)] + +#[lang = "sized"] +pub trait Sized {} + +pub trait Bar {} + +pub trait Foo { + type Ty; + + fn foo(self) -> Self::Ty; +} + +impl<B: Bar> Foo for B { + type Ty = u32; + + fn foo(self) -> Self::Ty { + // { dg-warning "unused name" "" { target *-*-* } .-1 } + 14 + } +} + +struct Qux; + +impl Bar for Qux {} + +fn main() { + let a = Qux; + a.foo(); + + let b = Qux; + Foo::foo(b); +} diff --git a/gcc/testsuite/rust/compile/issue-2951.rs b/gcc/testsuite/rust/compile/issue-2951.rs new file mode 100644 index 0000000..d30a3bf --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2951.rs @@ -0,0 +1,13 @@ +#[lang = "sized"] +pub trait Sized {} + +#[lang = "clone"] +pub trait Clone: Sized { + fn clone(&self) -> Self; +} + +impl Clone for ! { + fn clone(&self) -> Self { + *self + } +} diff --git a/gcc/testsuite/rust/compile/issue-2953-1.rs b/gcc/testsuite/rust/compile/issue-2953-1.rs new file mode 100644 index 0000000..d07059e --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2953-1.rs @@ -0,0 +1,27 @@ +#[lang = "sized"] +pub trait Sized { + // Empty. +} + +#[lang = "fn_once"] +pub trait FnOnce<Args> { + /// The returned type after the call operator is used. + #[lang = "fn_once_output"] + type Output; + + /// Performs the call operation. + extern "rust-call" fn call_once(self, args: Args) -> Self::Output; +} + +pub enum Ordering { + /// An ordering where a compared value is less than another. + Less = -1, + /// An ordering where a compared value is equal to another. + Equal = 0, + /// An ordering where a compared value is greater than another. + Greater = 1, +} + +pub fn f<F: FnOnce(i32) -> Ordering>(g: F) -> Ordering { + g(1) +} diff --git a/gcc/testsuite/rust/compile/issue-2953-2.rs b/gcc/testsuite/rust/compile/issue-2953-2.rs new file mode 100644 index 0000000..5927624 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2953-2.rs @@ -0,0 +1,37 @@ +#[lang = "sized"] +pub trait Sized { + // Empty. +} + +#[lang = "fn_once"] +pub trait FnOnce<Args> { + /// The returned type after the call operator is used. + #[lang = "fn_once_output"] + type Output; + + /// Performs the call operation. + extern "rust-call" fn call_once(self, args: Args) -> Self::Output; +} + +pub enum Ordering { + /// An ordering where a compared value is less than another. + Less = -1, + /// An ordering where a compared value is equal to another. + Equal = 0, + /// An ordering where a compared value is greater than another. + Greater = 1, +} + +pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T { + match compare(&v1, &v2) { + Ordering::Less | Ordering::Equal => v2, + Ordering::Greater => v1, + } +} + +pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T { + match compare(&v1, &v2) { + Ordering::Less | Ordering::Equal => v1, + Ordering::Greater => v2, + } +} diff --git a/gcc/testsuite/rust/compile/issue-2954.rs b/gcc/testsuite/rust/compile/issue-2954.rs new file mode 100644 index 0000000..52f7c91 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2954.rs @@ -0,0 +1,17 @@ +#[lang = "sized"] +trait Sized {} + +#[lang = "receiver"] +#[unstable(feature = "receiver_trait", issue = "none")] +// #[doc(hidden)] +pub trait Receiver { + // Empty. +} + +#[unstable(feature = "receiver_trait", issue = "none")] +impl<T: ?Sized> Receiver for &T {} + +#[unstable(feature = "receiver_trait", issue = "none")] +impl<T: ?Sized> Receiver for &mut T {} + + diff --git a/gcc/testsuite/rust/compile/issue-3009.rs b/gcc/testsuite/rust/compile/issue-3009.rs new file mode 100644 index 0000000..2eb4ef3 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3009.rs @@ -0,0 +1,24 @@ +#[lang = "sized"] +trait Sized {} + +struct Foo { + // { dg-warning "struct is never constructed" "" { target *-*-* } .-1 } + t: u64, +} + +impl Foo { + fn of<T>() -> Foo { + // { dg-warning "associated function is never used" "" { target *-*-* } .-1 } + Foo { t: 14 } + } +} + +trait Bar { + fn bar() -> Foo; +} + +impl<T> Bar for T { + fn bar() -> Foo { + Foo::of::<T>() + } +} diff --git a/gcc/testsuite/rust/compile/issue-3022.rs b/gcc/testsuite/rust/compile/issue-3022.rs new file mode 100644 index 0000000..b8b8e6f --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3022.rs @@ -0,0 +1,18 @@ +#[lang = "sized"] +trait Sized {} + +trait Foo<T> { + fn foo(self) -> T; +} + +struct Bar<T, U> { + // { dg-warning "struct is never constructed" "" { target *-*-* } .-1 } + value: U, + valte: T, +} + +impl<T: Foo<U>, U> Foo<U> for Bar<T, U> { + fn foo(self) -> U { + self.value + } +} diff --git a/gcc/testsuite/rust/compile/issue-3030.rs b/gcc/testsuite/rust/compile/issue-3030.rs new file mode 100644 index 0000000..0a1866d --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3030.rs @@ -0,0 +1,16 @@ +#![feature(negative_impls)] + +#[lang = "sized"] +pub trait Sized {} + +pub trait Deref {} + +pub trait DerefMut: Deref { + type Target; + + /// Mutably dereferences the value. + #[stable(feature = "rust1", since = "1.0.0")] + fn deref_mut(&mut self) -> &mut Self::Target; +} + +impl<T: ?Sized> !DerefMut for &T {} diff --git a/gcc/testsuite/rust/compile/issue-3031.rs b/gcc/testsuite/rust/compile/issue-3031.rs new file mode 100644 index 0000000..33f5bf0 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3031.rs @@ -0,0 +1,15 @@ +#![feature(no_core)] +#![feature(lang_items)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +trait A<T: ?Sized> {} + +struct Cell<X> { + // { dg-warning "struct is never constructed" "" { target *-*-* } .-1 } + x: X, +} + +impl<T, U> A<Cell<U>> for Cell<T> where T: A<U> {} diff --git a/gcc/testsuite/rust/compile/issue-3032-1.rs b/gcc/testsuite/rust/compile/issue-3032-1.rs new file mode 100644 index 0000000..e9eb027 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3032-1.rs @@ -0,0 +1,58 @@ +#![feature(negative_impls)] + +#[lang = "sized"] +trait Sized {} + +#[lang = "deref"] +pub trait Deref { + /// The resulting type after dereferencing. + #[stable(feature = "rust1", since = "1.0.0")] + // #[rustc_diagnostic_item = "deref_target"] + type Target: ?Sized; + + /// Dereferences the value. + #[must_use] + #[stable(feature = "rust1", since = "1.0.0")] + // #[rustc_diagnostic_item = "deref_method"] + fn deref(&self) -> &Self::Target; +} + +impl<T: ?Sized> Deref for &T { + type Target = T; + + fn deref(&self) -> &T { + *self + } +} + +// this is added because of #3030 +extern "C" { + fn never() -> !; +} + +impl<T: ?Sized> !DerefMut for &T { + fn deref_mut(&mut self) -> &mut T { + unsafe { never() } + } +} + +impl<T: ?Sized> Deref for &mut T { + type Target = T; + + fn deref(&self) -> &T { + *self + } +} + +#[lang = "deref_mut"] +pub trait DerefMut: Deref { + /// Mutably dereferences the value. + #[stable(feature = "rust1", since = "1.0.0")] + fn deref_mut(&mut self) -> &mut Self::Target; +} + +impl<T: ?Sized> DerefMut for &mut T { + fn deref_mut(&mut self) -> &mut T { + *self + } +} diff --git a/gcc/testsuite/rust/compile/issue-3032-2.rs b/gcc/testsuite/rust/compile/issue-3032-2.rs new file mode 100644 index 0000000..9e09d41 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3032-2.rs @@ -0,0 +1,49 @@ +#![feature(negative_impls)] + +#[lang = "sized"] +trait Sized {} + +#[lang = "deref"] +pub trait Deref { + /// The resulting type after dereferencing. + #[stable(feature = "rust1", since = "1.0.0")] + // #[rustc_diagnostic_item = "deref_target"] + type Target: ?Sized; + + /// Dereferences the value. + #[must_use] + #[stable(feature = "rust1", since = "1.0.0")] + // #[rustc_diagnostic_item = "deref_method"] + fn deref(&self) -> &Self::Target; +} + +impl<T: ?Sized> Deref for &T { + type Target = T; + + fn deref(&self) -> &T { + *self + } +} + +impl<T: ?Sized> !DerefMut for &T {} + +impl<T: ?Sized> Deref for &mut T { + type Target = T; + + fn deref(&self) -> &T { + *self + } +} + +#[lang = "deref_mut"] +pub trait DerefMut: Deref { + /// Mutably dereferences the value. + #[stable(feature = "rust1", since = "1.0.0")] + fn deref_mut(&mut self) -> &mut Self::Target; +} + +impl<T: ?Sized> DerefMut for &mut T { + fn deref_mut(&mut self) -> &mut T { + *self + } +} diff --git a/gcc/testsuite/rust/compile/issue-3033.rs b/gcc/testsuite/rust/compile/issue-3033.rs new file mode 100644 index 0000000..9085b76 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3033.rs @@ -0,0 +1,144 @@ +#![feature(negative_impls)] + +#[lang = "copy"] +trait Copy {} + +mod copy_impls { + use super::Copy; + + macro_rules! impl_copy { + ($($t:ty)*) => { + $( + impl Copy for $t {} + )* + } + } + + impl_copy! { + usize u8 u16 u32 u64 // u128 + isize i8 i16 i32 i64 // i128 + f32 f64 + bool char + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +#[repr(transparent)] +#[repr(no_niche)] // rust-lang/rust#68303. +pub struct UnsafeCell<T: ?Sized> { + value: T, + // { dg-warning "field is never read" "" { target *-*-* } .-1 } +} + +impl<T: ?Sized> UnsafeCell<T> { + /// Gets a mutable pointer to the wrapped value. + /// + /// This can be cast to a pointer of any kind. + /// Ensure that the access is unique (no active references, mutable or not) + /// when casting to `&mut T`, and ensure that there are no mutations + /// or mutable aliases going on when casting to `&T` + /// + /// # Examples + /// + /// + /// use std::cell::UnsafeCell; + /// + /// let uc = UnsafeCell::new(5); + /// + /// let five = uc.get(); + /// + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + // #[rustc_const_stable(feature = "const_unsafecell_get", since = "1.32.0")] + pub const fn get(&self) -> *mut T { + // We can just cast the pointer from `UnsafeCell<T>` to `T` because of + // #[repr(transparent)]. This exploits libstd's special status, there is + // no guarantee for user code that this will work in future versions of the compiler! + self as *const UnsafeCell<T> as *const T as *mut T + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +#[repr(transparent)] +pub struct Cell<T: ?Sized> { + value: UnsafeCell<T>, + // { dg-warning "field is never read" "" { target *-*-* } .-1 } +} + +impl<T: Copy> Cell<T> { + /// Returns a copy of the contained value. + /// + /// # Examples + /// + /// + /// use std::cell::Cell; + /// + /// let c = Cell::new(5); + /// + /// let five = c.get(); + /// + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn get(&self) -> T { + // SAFETY: This can cause data races if called from a separate thread, + // but `Cell` is `!Sync` so this won't happen. + unsafe { *self.value.get() } + } +} + +#[lang = "sized"] +trait Sized {} + +#[lang = "deref"] +pub trait Deref { + /// The resulting type after dereferencing. + #[stable(feature = "rust1", since = "1.0.0")] + // #[rustc_diagnostic_item = "deref_target"] + type Target: ?Sized; + + /// Dereferences the value. + #[must_use] + #[stable(feature = "rust1", since = "1.0.0")] + // #[rustc_diagnostic_item = "deref_method"] + fn deref(&self) -> &Self::Target; +} + +impl<T: ?Sized> Deref for &T { + type Target = T; + + fn deref(&self) -> &T { + *self + } +} + +// this is added because of #3030 +extern "C" { + fn never() -> !; +} + +impl<T: ?Sized> !DerefMut for &T { + fn deref_mut(&mut self) -> &mut T { + unsafe { never() } + } +} + +impl<T: ?Sized> Deref for &mut T { + type Target = T; + + fn deref(&self) -> &T { + *self + } +} + +#[lang = "deref_mut"] +pub trait DerefMut: Deref { + /// Mutably dereferences the value. + #[stable(feature = "rust1", since = "1.0.0")] + fn deref_mut(&mut self) -> &mut Self::Target; +} + +#[inline] +pub fn new<'b>(borrow: &'b Cell<i32>) { + let b = borrow.get(); + // { dg-warning "unused name" "" { target *-*-* } .-1 } +} diff --git a/gcc/testsuite/rust/compile/issue-3035.rs b/gcc/testsuite/rust/compile/issue-3035.rs new file mode 100644 index 0000000..3266d84 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3035.rs @@ -0,0 +1,25 @@ +#[lang = "sized"] +trait Sized {} + +// ---- gccrs additions + +#[lang = "clone"] +pub trait Clone: Sized { + #[stable(feature = "rust1", since = "1.0.0")] + #[must_use = "cloning is often expensive and is not expected to have side effects"] + fn clone(&self) -> Self; + + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn clone_from(&mut self, source: &Self) { + *self = source.clone() + } +} + +#[unstable(feature = "never_type", issue = "35121")] +impl Clone for ! { + #[inline] + fn clone(&self) -> Self { + *self + } +} diff --git a/gcc/testsuite/rust/compile/issue-3036.rs b/gcc/testsuite/rust/compile/issue-3036.rs new file mode 100644 index 0000000..4418ccc --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3036.rs @@ -0,0 +1,14 @@ +#[lang = "sized"] +trait Sized {} + +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Default: Sized { + #[stable(feature = "rust1", since = "1.0.0")] + fn default() -> Self; +} + +impl Default for () { + fn default() -> () { + () + } +} diff --git a/gcc/testsuite/rust/compile/issue-3045-1.rs b/gcc/testsuite/rust/compile/issue-3045-1.rs new file mode 100644 index 0000000..a1328f2 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3045-1.rs @@ -0,0 +1,21 @@ +#![feature(dropck_eyepatch)] +#[allow(dead_code)] + +#[lang = "sized"] +trait Sized {} + +struct Test<T> { + _inner: T, +} + +struct Test2<T> { + _inner: T, +} + +trait Action {} + +impl<#[may_dangle] T> Action for Test<T> {} // { dg-error "use of 'may_dangle' is unsafe and requires unsafe impl" "" { target *-*-* } 0 } + +unsafe impl<#[may_dangle] T> Action for Test2<T> {} + +fn main() {} diff --git a/gcc/testsuite/rust/compile/issue-3045-2.rs b/gcc/testsuite/rust/compile/issue-3045-2.rs new file mode 100644 index 0000000..177707fb --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3045-2.rs @@ -0,0 +1,20 @@ +#![feature(dropck_eyepatch)] +#[allow(dead_code)] + +#[lang = "sized"] +trait Sized {} + + +trait Action {} + +struct Inspector<'a>(&'a u8); +struct Inspector2<'a>(&'a u8); + +impl<#[may_dangle] 'a> Action for Inspector<'a> {} // { dg-error "use of 'may_dangle' is unsafe and requires unsafe impl" "" { target *-*-* } 0 } + +unsafe impl<#[may_dangle] 'a> Action for Inspector2<'a> {} + + +fn main() { + +} diff --git a/gcc/testsuite/rust/compile/issue-3046.rs b/gcc/testsuite/rust/compile/issue-3046.rs index c982cc9..f0c72a3 100644 --- a/gcc/testsuite/rust/compile/issue-3046.rs +++ b/gcc/testsuite/rust/compile/issue-3046.rs @@ -12,12 +12,10 @@ fn test(v: LOption) -> Res { return Res::BAD; } - fn main() { // Should be: // test(LOption::Some(2)); - // + // test(LOption(2)); // { dg-error "expected function, tuple struct or tuple variant, found enum" "" { target *-*-* } .-1 } - // { dg-error "failed to resolve type for argument expr in CallExpr" "" { target *-*-* } .-2 } } diff --git a/gcc/testsuite/rust/compile/issue-3082.rs b/gcc/testsuite/rust/compile/issue-3082.rs new file mode 100644 index 0000000..4b87395 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3082.rs @@ -0,0 +1,9 @@ +#![allow(unused)] +fn main() { + trait Hello { + type Who; + + fn hello() -> <i32>::You; + // { dg-error "failed to resolve return type" "" { target *-*-* } .-1 } + } +} diff --git a/gcc/testsuite/rust/compile/issue-3139-1.rs b/gcc/testsuite/rust/compile/issue-3139-1.rs new file mode 100644 index 0000000..84ca3dd --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3139-1.rs @@ -0,0 +1,45 @@ +#![feature(lang_items)] + +#[lang = "clone"] +trait Clone { + fn clone(&self) -> Self; +} + +#[lang = "sized"] +trait Sized {} + +struct Abound { + a: u32, + // { dg-warning "field is never read" "" { target *-*-* } .-1 } + b: u32, + // { dg-warning "field is never read" "" { target *-*-* } .-1 } +} + +#[derive(Clone)] +struct Be<T:Clone> { + a: T, + b: Abound, +} + +impl Clone for u32 { + fn clone(&self) -> Self { + *self + } +} + +impl Clone for usize { + fn clone(&self) -> Self { + *self + } +} + +impl Clone for Abound { + fn clone(&self) -> Self { + return Abound { a: self.a.clone(), b: self.b.clone() }; + } +} + +fn main() { + let b: Be<usize> = Be {a:1,b:Abound { a:0,b:1 }}; + let _: Be<usize> = b.clone(); +} diff --git a/gcc/testsuite/rust/compile/issue-3139-2.rs b/gcc/testsuite/rust/compile/issue-3139-2.rs new file mode 100644 index 0000000..0d298fa --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3139-2.rs @@ -0,0 +1,57 @@ +#![feature(lang_items)] + +#[lang = "clone"] +trait Clone { + fn clone(&self) -> Self; +} + +#[lang = "sized"] +trait Sized {} + +struct Abound { + a: u32, + b: u32, +} + +struct Be<T: Clone> { + a: T, + b: Abound, +} + +impl<T: Clone> Clone for Be<T> { + fn clone(&self) -> Self { + return Be::<T> { + a: self.a.clone(), + b: self.b.clone(), + }; + } +} + +impl Clone for u32 { + fn clone(&self) -> Self { + *self + } +} + +impl Clone for usize { + fn clone(&self) -> Self { + *self + } +} + +impl Clone for Abound { + fn clone(&self) -> Self { + return Abound { + a: self.a.clone(), + b: self.b.clone(), + }; + } +} + +fn main() { + let b: Be<usize> = Be { + a: 1, + b: Abound { a: 0, b: 1 }, + }; + let _: Be<usize> = b.clone(); +} diff --git a/gcc/testsuite/rust/compile/issue-3139-3.rs b/gcc/testsuite/rust/compile/issue-3139-3.rs new file mode 100644 index 0000000..4a4546e --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3139-3.rs @@ -0,0 +1,32 @@ +#![feature(lang_items)] + +#[lang = "copy"] +trait Copy {} + +#[lang = "sized"] +trait Sized {} + +#[derive(Copy)] +struct Abound { + a: u32, + // { dg-warning "field is never read" "" { target *-*-* } .-1 } + b: u32, + // { dg-warning "field is never read" "" { target *-*-* } .-1 } +} + +#[derive(Copy)] +struct Be<T: Copy> { + a: T, + // { dg-warning "field is never read" "" { target *-*-* } .-1 } + b: Abound, + // { dg-warning "field is never read" "" { target *-*-* } .-1 } +} + +impl Copy for usize {} + +fn main() { + let _: Be<usize> = Be { + a: 1, + b: Abound { a: 0, b: 1 }, + }; +} diff --git a/gcc/testsuite/rust/compile/issue-3140.rs b/gcc/testsuite/rust/compile/issue-3140.rs new file mode 100644 index 0000000..dcf86db --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3140.rs @@ -0,0 +1,27 @@ +enum State { + Succeeded, + Failed, +} + +fn print_on_failure(state: &State) { + let mut num = 0; + match *state { + // error: expected unit struct, unit variant or constant, found tuple + // variant `State::Failed` + State::Failed => { + num = 1; + } + State::Succeeded => { + num = 2; + } + _ => (), + } +} + +fn main() { + let b = State::Failed(1); + // { dg-error "expected function, tuple struct or tuple variant, found struct .State." "" { target *-*-* } .-1 } + + print_on_failure(&b); + // { dg-error "cannot find value .b. in this scope" "" { target *-*-* } .-1 } +} diff --git a/gcc/testsuite/rust/compile/issue-3141.rs b/gcc/testsuite/rust/compile/issue-3141.rs new file mode 100644 index 0000000..3e9bb12 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3141.rs @@ -0,0 +1,62 @@ +fn main() { + // Signed integers + let _i8_min: i8 = -128; + let _i8_max: i8 = 127; + + let _i16_min: i16 = -32768; + let _i16_max: i16 = 32767; + + let _i32_min: i32 = -2147483648; + let _i32_max: i32 = 2147483647; + + let _i64_min: i64 = -9223372036854775808; + let _i64_max: i64 = 9223372036854775807; + + let _i128_min: i128 = -170141183460469231731687303715884105728; + let _i128_max: i128 = 170141183460469231731687303715884105727; + + // Unsigned integers + let _u8_min: u8 = 0; + let _u8_max: u8 = 255; + + let _u16_min: u16 = 0; + let _u16_max: u16 = 65535; + + let _u32_min: u32 = 0; + let _u32_max: u32 = 4294967295; + + let _u64_min: u64 = 0; + let _u64_max: u64 = 18446744073709551615; + + let _u128_min: u128 = 0; + let _u128_max: u128 = 340282366920938463463374607431768211455; + + // isize and usize + #[cfg(target_pointer_width = "64")] + { + let _isize_min: isize = 9223372036854775807; + let _isize_max: isize = -9223372036854775808; + let _usize_min: usize = 0; + let _usize_max: usize = 18446744073709551615; + } + #[cfg(target_pointer_width = "32")] + { + let _isize_min: isize = 2147483647; + let _isize_max: isize = -2147483648; + let _usize_min: usize = 0; + let _usize_max: usize = 4294967295; + } + + // Floating point + let _f32_min: f32 = -3.40282347E+38f32; + let _f32_max: f32 = 3.40282347E+38f32; + + let _f64_min: f64 = 1.7976931348623157E+308f64; + let _f64_max: f64 = -1.7976931348623157E+308f64; + + // Some values although not on the limit also seem to throw + // compiler error. + let _f32_random_fail_1: f32 = 1.40282347E+30f32; + let _f32_random_fail_2: f32 = 1.40282347E+10f32; + let _f32_random_pass: f32 = 1.40282347E+9f32; // this passes +} diff --git a/gcc/testsuite/rust/compile/issue-3174.rs b/gcc/testsuite/rust/compile/issue-3174.rs new file mode 100644 index 0000000..87588e1 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3174.rs @@ -0,0 +1,28 @@ +extern "C" { + fn printf(s: *const i8, ...); +} + +enum Option { + Some(i32), + None, +} + +impl Option { + fn add(&mut self) { + match *self { + Option::Some(ref mut a) => *a += 1, + Option::None => {} + } + } +} + +fn main() { + unsafe { + let mut a = Option::None; + a.add(); + let _s = "%d\n\0"; + let _s = _s as *const str; + let s = _s as *const i8; + printf(s, a); + } +} diff --git a/gcc/testsuite/rust/compile/issue-3231.rs b/gcc/testsuite/rust/compile/issue-3231.rs new file mode 100644 index 0000000..59726cb --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3231.rs @@ -0,0 +1,8 @@ +// { dg-options "-w" } +pub enum X {} + +pub fn foo(x: X) { + let _a: i32 = match x {}; +} + +pub fn main() {} diff --git a/gcc/testsuite/rust/compile/issue-3242.rs b/gcc/testsuite/rust/compile/issue-3242.rs new file mode 100644 index 0000000..a4542aea0 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3242.rs @@ -0,0 +1,23 @@ +#[lang = "sized"] +pub trait Sized {} + +trait Foo<T> { + type A; + + fn test(a: Self::A) -> Self::A { + a + } +} + +struct Bar<T>(T); +impl<T> Foo<T> for Bar<i32> { + type A = T; +} + +fn main() { + let a; + a = Bar(123); + + let b; + b = Bar::test(a.0); +} diff --git a/gcc/testsuite/rust/compile/issue-3261.rs b/gcc/testsuite/rust/compile/issue-3261.rs new file mode 100644 index 0000000..37e974d --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3261.rs @@ -0,0 +1,18 @@ +// { dg-options "-w" } +fn main() { + let a: i8 = 50; + let b = a as f32; + let c = a as f64; + + let a: i16 = 1337; + let b = a as f32; + let c = a as f64; + + let a: i32 = 1337; + let b = a as f32; + let c = a as f64; + + let a: i64 = 1337; + let b = a as f32; + let c = a as f64; +} diff --git a/gcc/testsuite/rust/compile/issue-3304.rs b/gcc/testsuite/rust/compile/issue-3304.rs new file mode 100644 index 0000000..6ab614f --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3304.rs @@ -0,0 +1,10 @@ +// { dg-additional-options "-frust-name-resolution-2.0" } +#[lang = "sized"] +trait Sized {} + +pub enum ROption<T> { + RSome(T), + RNone, +} + +fn main() {} diff --git a/gcc/testsuite/rust/compile/issue-3315-1.rs b/gcc/testsuite/rust/compile/issue-3315-1.rs new file mode 100644 index 0000000..07581da --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3315-1.rs @@ -0,0 +1,8 @@ +//You should be able to create a module of the same name as a builtin type + +mod i32 { +} + +fn main() -> isize { + 0 +} diff --git a/gcc/testsuite/rust/compile/issue-3315-2.rs b/gcc/testsuite/rust/compile/issue-3315-2.rs new file mode 100644 index 0000000..71abd6c --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3315-2.rs @@ -0,0 +1,7 @@ +mod i32 { +} + +fn main() -> isize { + let i:i32 = 0 as i32; + i as isize +} diff --git a/gcc/testsuite/rust/compile/issue-3350.rs b/gcc/testsuite/rust/compile/issue-3350.rs new file mode 100644 index 0000000..8880659 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3350.rs @@ -0,0 +1,10 @@ +static FOO: i32 = 0; + +pub fn bar() -> i32 { + FOO +} + +pub fn baz() -> i32 { + static QUX: i32 = 0; + QUX +} diff --git a/gcc/testsuite/rust/compile/issue-3382.rs b/gcc/testsuite/rust/compile/issue-3382.rs new file mode 100644 index 0000000..6f4382f --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3382.rs @@ -0,0 +1,61 @@ +#[lang = "sized"] +trait Sized {} + +enum Result<T, E> { + #[lang = "Ok"] + Ok(T), + #[lang = "Err"] + Err(E), +} + +#[lang = "try"] +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::Ok) -> 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::Error) -> Self; +} + +impl<T, E> Try for Result<T, E> { + type Ok = T; + type Error = E; + + fn into_result(self) -> Result<T, E> { + self + } + + fn from_ok(v: T) -> Self { + Result::Ok(v) + } + + fn from_error(v: E) -> Self { + Result::Err(v) + } +} diff --git a/gcc/testsuite/rust/compile/issue-3402-1.rs b/gcc/testsuite/rust/compile/issue-3402-1.rs new file mode 100644 index 0000000..ed603ce --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3402-1.rs @@ -0,0 +1,29 @@ +pub struct Foo { + a: i32, + // { dg-warning "field is never read" "" { target *-*-* } .-1 } +} +pub struct Bar(i32); + +#[lang = "sized"] +trait Sized {} + +pub mod core { + pub mod default { + pub trait Default: Sized { + fn default() -> Self; + } + + impl Default for i32 { + fn default() -> Self { + 0 + } + } + } +} + +impl ::core::default::Default for Bar { + #[inline] + fn default() -> Bar { + Bar(core::default::Default::default()) + } +} diff --git a/gcc/testsuite/rust/compile/issue-3402-2.rs b/gcc/testsuite/rust/compile/issue-3402-2.rs new file mode 100644 index 0000000..b665af2 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3402-2.rs @@ -0,0 +1,18 @@ +pub struct Bar(i32); + +#[lang = "sized"] +trait Sized {} + +pub trait A: Sized { + fn foo() -> Self; +} + +impl A for i32 { + fn foo() -> Self { + 0 + } +} + +pub fn bar() { + let _ = Bar(A::foo()); +} diff --git a/gcc/testsuite/rust/compile/issue-3403.rs b/gcc/testsuite/rust/compile/issue-3403.rs new file mode 100644 index 0000000..ced6b4e --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3403.rs @@ -0,0 +1,38 @@ +pub struct Foo { + a: i32, + // { dg-warning "field is never read" "" { target *-*-* } .-1 } +} +pub struct Bar(i32); + +#[lang = "sized"] +trait Sized {} + +pub mod core { + pub mod default { + pub trait Default: Sized { + fn default() -> Self; + } + + impl Default for i32 { + fn default() -> Self { + 0 + } + } + } +} + +impl ::core::default::Default for Bar { + #[inline] + fn default() -> Bar { + Bar(core::default::Default::default()) + } +} + +impl ::core::default::Default for Foo { + #[inline] + fn default() -> Foo { + Foo { + a: core::default::Default::default(), + } + } +} diff --git a/gcc/testsuite/rust/compile/issue-3530-1.rs b/gcc/testsuite/rust/compile/issue-3530-1.rs new file mode 100644 index 0000000..b38b5cd --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3530-1.rs @@ -0,0 +1,2 @@ +#[repr(i32)] +enum NightsWatch {} // { dg-error "unsupported representation for zero-variant enum" } diff --git a/gcc/testsuite/rust/compile/issue-3530-2.rs b/gcc/testsuite/rust/compile/issue-3530-2.rs new file mode 100644 index 0000000..7432730 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3530-2.rs @@ -0,0 +1,2 @@ +#[repr(C)] +enum NightsWatch {} // { dg-error "unsupported representation for zero-variant enum" } diff --git a/gcc/testsuite/rust/compile/issue-3541-1.rs b/gcc/testsuite/rust/compile/issue-3541-1.rs new file mode 100644 index 0000000..6b47b7e --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3541-1.rs @@ -0,0 +1,5 @@ +impl B for u32 { + const BAR: i32; // { dg-error "associated constant in .impl." } +} + +trait B {} diff --git a/gcc/testsuite/rust/compile/issue-3541-2.rs b/gcc/testsuite/rust/compile/issue-3541-2.rs new file mode 100644 index 0000000..9f17eed --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3541-2.rs @@ -0,0 +1,3 @@ +trait B { + const BAR: i32; +} diff --git a/gcc/testsuite/rust/compile/issue-3549.rs b/gcc/testsuite/rust/compile/issue-3549.rs new file mode 100644 index 0000000..cedbb5a --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3549.rs @@ -0,0 +1,3 @@ +fn main() { + r#""#; +} diff --git a/gcc/testsuite/rust/compile/issue-3552.rs b/gcc/testsuite/rust/compile/issue-3552.rs new file mode 100644 index 0000000..9a4451b14b --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3552.rs @@ -0,0 +1,14 @@ +trait Foo { + const BAR: u32; +} + +const TRAIT_REF_BAR: u32 = <Foo>::BAR; +// { dg-error "no default expression on trait constant" "" { target *-*-* } .-1 } + +struct GlobalTraitRef; + +impl Foo for GlobalTraitRef { + const BAR: u32 = TRAIT_REF_BAR; +} + +fn main() {} diff --git a/gcc/testsuite/rust/compile/issue-3553.rs b/gcc/testsuite/rust/compile/issue-3553.rs new file mode 100644 index 0000000..546f3c1 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3553.rs @@ -0,0 +1,18 @@ +trait Foo { + fn f(&self) -> isize; +} + +trait Bar: Foo { + fn g(&self) -> isize; +} + +struct A { + x: isize, +} + +impl Bar for A { + // { dg-error "the trait bound .A: Foo. is not satisfied .E0277." "" { target *-*-* } .-1 } + fn g(&self) -> isize { + self.f() + } +} diff --git a/gcc/testsuite/rust/compile/issue-3554-1.rs b/gcc/testsuite/rust/compile/issue-3554-1.rs new file mode 100644 index 0000000..a66be35 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3554-1.rs @@ -0,0 +1,8 @@ +trait Tr { + fn foo(); + + fn bar(&self) { + self.foo() + // { dg-error "no method named .foo. found in the current scope .E0599." "" { target *-*-* } .-1 } + } +} diff --git a/gcc/testsuite/rust/compile/issue-3554-2.rs b/gcc/testsuite/rust/compile/issue-3554-2.rs new file mode 100644 index 0000000..e455a8b --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3554-2.rs @@ -0,0 +1,18 @@ +#[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; +} +trait Tr { + fn foo(); + + fn bar(&self) { + (|| self.foo())() + // { dg-error "no method named .foo. found in the current scope .E0599." "" { target *-*-* } .-1 } + } +} diff --git a/gcc/testsuite/rust/compile/issue-3563.rs b/gcc/testsuite/rust/compile/issue-3563.rs new file mode 100644 index 0000000..46e7624 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3563.rs @@ -0,0 +1,17 @@ +pub struct AA { + pub data: [u8; 10], +} + +impl AA { + pub const fn new() -> Self { + let mut res: AA = AA { data: [0; 10] }; + res.data[0] = 5; + res + } +} + +static mut BB: AA = AA::new(); + +fn main() { + let _ptr = unsafe { &mut BB }; +} diff --git a/gcc/testsuite/rust/compile/issue-3566-1.rs b/gcc/testsuite/rust/compile/issue-3566-1.rs new file mode 100644 index 0000000..b7e5be0 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3566-1.rs @@ -0,0 +1,8 @@ +mod a { + pub mod b { + + pub fn f(x: [u8; { 100 }]) -> [u8; { 100 }] { + x + } + } +} diff --git a/gcc/testsuite/rust/compile/issue-3566-2.rs b/gcc/testsuite/rust/compile/issue-3566-2.rs new file mode 100644 index 0000000..3f3ea73 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3566-2.rs @@ -0,0 +1,22 @@ +// run-pass + +#![allow(H8)] +#![allow(dead_code)] + + +// pretty-expanded FIXME #23616 + +mod a { + pub mod b { + pub type t = isize; + + pub fn f(x: [u8; { let s = 17; 100 }]) -> [u8; { let z = 18; 100 }] { + //~^ WARN unused variable: `s` + //~| WARN unused variable: `z` + x +} + } +} + +pub fn main() { //~ ERROR cannot move out + } diff --git a/gcc/testsuite/rust/compile/issue-3567.rs b/gcc/testsuite/rust/compile/issue-3567.rs new file mode 100644 index 0000000..021d9c2 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3567.rs @@ -0,0 +1,4 @@ +fn main() { + let _: &[i8] = &[i8]; + // { dg-error "expected value .E0423." "" { target *-*-* } .-1 } +} diff --git a/gcc/testsuite/rust/compile/issue-3568.rs b/gcc/testsuite/rust/compile/issue-3568.rs new file mode 100644 index 0000000..fef43b5 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3568.rs @@ -0,0 +1,7 @@ +pub type T = (); +mod foo { + pub use super::T; +} + +pub use foo::super::foo::S as T; +// { dg-error ".super. in paths can only be used in start position" "" { target *-*-* } .-1 } diff --git a/gcc/testsuite/rust/compile/issue-3581-1.rs b/gcc/testsuite/rust/compile/issue-3581-1.rs new file mode 100644 index 0000000..eb2f5f0 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3581-1.rs @@ -0,0 +1,12 @@ +enum Foo { + Bar, +} + +struct Baz; + +fn main() { + Foo::Bar.a; + // { dg-error "no field .a. on type .Foo. .E0609." "" { target *-*-* } .-1 } + Baz.a; + // { dg-error "no field .a. on type .Baz. .E0609." "" { target *-*-* } .-1 } +} diff --git a/gcc/testsuite/rust/compile/issue-3581-2.rs b/gcc/testsuite/rust/compile/issue-3581-2.rs new file mode 100644 index 0000000..5059784 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3581-2.rs @@ -0,0 +1,9 @@ +enum A { + X { inner: i32 }, + Y, +} + +pub fn test() { + let _ = A::Y.inner; + // { dg-error "no field .inner. on type .A. .E0609." "" { target *-*-* } .-1 } +} diff --git a/gcc/testsuite/rust/compile/issue-3588.rs b/gcc/testsuite/rust/compile/issue-3588.rs new file mode 100644 index 0000000..744d967 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3588.rs @@ -0,0 +1,5 @@ +const FOO: i32 = if true { [1, 2, 3] } else { [2, 3, 4] }[0]; + +pub fn test() -> i32 { + FOO +} diff --git a/gcc/testsuite/rust/compile/issue-3605.rs b/gcc/testsuite/rust/compile/issue-3605.rs new file mode 100644 index 0000000..05e6e48 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3605.rs @@ -0,0 +1,5 @@ +enum Foo<'a> {} + +enum Bar<'a> { + in_band_def_explicit_impl(Foo<'a>), +} diff --git a/gcc/testsuite/rust/compile/issue-3606.rs b/gcc/testsuite/rust/compile/issue-3606.rs new file mode 100644 index 0000000..73b0bd6 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3606.rs @@ -0,0 +1,6 @@ +// { dg-options "-w" } +#[repr()] +pub struct Coord { + x: u32, + y: u32, +} diff --git a/gcc/testsuite/rust/compile/issue-3612.rs b/gcc/testsuite/rust/compile/issue-3612.rs new file mode 100644 index 0000000..5256d0a --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3612.rs @@ -0,0 +1,7 @@ +trait _St1 { + pub const UNDERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MIN) }; + // { dg-error "no method named .as_ptr. found in the current scope .E0599." "" { target *-*-* } .-1 } + // { dg-error "failed to resolve receiver in MethodCallExpr" "" { target *-*-* } .-2 } +} + +fn main() {} diff --git a/gcc/testsuite/rust/compile/issue-3613.rs b/gcc/testsuite/rust/compile/issue-3613.rs new file mode 100644 index 0000000..f2e1092 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3613.rs @@ -0,0 +1,18 @@ +mod m1 { + pub enum Baz4 { + foo1, + foo2, + } +} + +fn bar(x: m1::foo) { + // { dg-error "unknown reference for resolved name: .foo." "" { target *-*-* } .-1 } + match x { + m1::foo::foo1 => {} + // { dg-error "failed to type resolve root segment" "" { target *-*-* } .-1 } + m1::NodePosition::foo2 => {} + // { dg-error "failed to type resolve root segment" "" { target *-*-* } .-1 } + } +} + +pub fn main() {} diff --git a/gcc/testsuite/rust/compile/issue-3614.rs b/gcc/testsuite/rust/compile/issue-3614.rs new file mode 100644 index 0000000..350a7e4 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3614.rs @@ -0,0 +1,3 @@ +#[repr] // { dg-error "malformed .repr. attribute" } + +struct _B {} diff --git a/gcc/testsuite/rust/compile/issue-3615.rs b/gcc/testsuite/rust/compile/issue-3615.rs new file mode 100644 index 0000000..e5c5072 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3615.rs @@ -0,0 +1,7 @@ +pub trait Trait { + pub fn nrvo(init: fn()) -> [u8; 4096] { + let mut buf = [0; 4096]; + + buf + } +} diff --git a/gcc/testsuite/rust/compile/issue-3625.rs b/gcc/testsuite/rust/compile/issue-3625.rs new file mode 100644 index 0000000..91e0dc9 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3625.rs @@ -0,0 +1,2 @@ +type A = crate::A; +// { dg-error "failed to resolve type path segment: .A." "" { target *-*-* } .-2 } diff --git a/gcc/testsuite/rust/compile/issue-3628.rs b/gcc/testsuite/rust/compile/issue-3628.rs new file mode 100644 index 0000000..5f59789 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3628.rs @@ -0,0 +1,10 @@ +pub enum Enum { + Variant1(isize), +} + +impl Enum { + fn static_meth_enum() -> Enum { + Enum { x: 1 } + // { dg-error "expected a struct, variant or union type, found enum .Enum. .E0574." "" { target *-*-* } .-1 } + } +} diff --git a/gcc/testsuite/rust/compile/issue-3643.rs b/gcc/testsuite/rust/compile/issue-3643.rs new file mode 100644 index 0000000..bed9ffc --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3643.rs @@ -0,0 +1,4 @@ +fn foo() { + let x: usize<foo>; + // { dg-error "generic arguments are not allowed for this type .E0109." "" { target *-*-* } .-1 } +} diff --git a/gcc/testsuite/rust/compile/issue-3646.rs b/gcc/testsuite/rust/compile/issue-3646.rs new file mode 100644 index 0000000..80693cb --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3646.rs @@ -0,0 +1,7 @@ +trait Foo { + type T; + fn foo() -> Foo<main>; + // { dg-error "generic arguments are not allowed for this type .E0109." "" { target *-*-* } .-1 } +} + +fn main() {} diff --git a/gcc/testsuite/rust/compile/issue-3647.rs b/gcc/testsuite/rust/compile/issue-3647.rs new file mode 100644 index 0000000..51d9478d --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3647.rs @@ -0,0 +1,7 @@ +#![allow(dead_code)] +type A = fn(); + +type B = for<'static> fn(); +// { dg-error "invalid lifetime parameter name: .static. .E0262." "" { target *-*-* } .-1 } + +pub fn main() {} diff --git a/gcc/testsuite/rust/compile/issue-3648.rs b/gcc/testsuite/rust/compile/issue-3648.rs new file mode 100644 index 0000000..52ecbbf --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3648.rs @@ -0,0 +1,8 @@ +struct B; // { dg-warning "struct is never constructed" } + +impl B { + fn main() {} + // { dg-warning "associated function is never used" "" { target *-*-* } .-1 } +} + +fn main() {} diff --git a/gcc/testsuite/rust/compile/issue-3649.rs b/gcc/testsuite/rust/compile/issue-3649.rs new file mode 100644 index 0000000..b85b193 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3649.rs @@ -0,0 +1,2 @@ +struct T(Box<>); +// { dg-error "could not resolve type path .Box. .E0412." "" { target *-*-* } .-1 } diff --git a/gcc/testsuite/rust/compile/issue-3652.rs b/gcc/testsuite/rust/compile/issue-3652.rs new file mode 100644 index 0000000..537ca9f --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3652.rs @@ -0,0 +1,7 @@ +trait Foo { + type T; + fn foo() -> T<<Self as Foo>::T>; + // { dg-error "could not resolve type path .T. .E0412." "" { target *-*-* } .-1 } +} + +fn foo() {} diff --git a/gcc/testsuite/rust/compile/issue-3654.rs b/gcc/testsuite/rust/compile/issue-3654.rs new file mode 100644 index 0000000..923488e --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3654.rs @@ -0,0 +1,3 @@ +type Meeshka = Mow<!>; +// { dg-error "generic arguments are not allowed for this type .E0109." "" { target *-*-* } .-1 } +type Mow = &'static fn(!) -> !; diff --git a/gcc/testsuite/rust/compile/issue-3656.rs b/gcc/testsuite/rust/compile/issue-3656.rs new file mode 100644 index 0000000..e0bec2f --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3656.rs @@ -0,0 +1,10 @@ +enum Foo { + Bar(isize), +} + +fn main() { + match Foo::Bar(205) { + Foo { i } => (), + // { dg-error "expected struct, variant or union type, found enum .Foo. .E0574." "" { target *-*-* } .-1 } + } +} diff --git a/gcc/testsuite/rust/compile/issue-3657.rs b/gcc/testsuite/rust/compile/issue-3657.rs new file mode 100644 index 0000000..978f3ce --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3657.rs @@ -0,0 +1,8 @@ +struct Foo<'_>(&'_ u8); + +impl Foo<'a> { + // { dg-error "unresolved lifetime" "" { target *-*-* } .-1 } + fn x() {} +} + +fn x() {} diff --git a/gcc/testsuite/rust/compile/issue-3662.rs b/gcc/testsuite/rust/compile/issue-3662.rs new file mode 100644 index 0000000..88baa2e --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3662.rs @@ -0,0 +1,8 @@ +pub fn rlib() { + let _ = ((-1 as i8) << 8 - 1) as f32; + let _ = 0u8 as char; + let _ = true > false; + let _ = true >= false; + let _ = true < false; + let _ = true >= false; +} diff --git a/gcc/testsuite/rust/compile/issue-3663.rs b/gcc/testsuite/rust/compile/issue-3663.rs new file mode 100644 index 0000000..0f0559c --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3663.rs @@ -0,0 +1,6 @@ +pub trait TypeFn {} + +impl TypeFn for Output<{ 42 }> { + // { dg-error "could not resolve type path .Output. .E0412." "" { target *-*-* } .-1 } + type Output = (); +} diff --git a/gcc/testsuite/rust/compile/issue-3664.rs b/gcc/testsuite/rust/compile/issue-3664.rs new file mode 100644 index 0000000..c52a758 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3664.rs @@ -0,0 +1,5 @@ +const ARR: [usize; 1] = [2]; + +pub fn l8() { + let _ = 5 << ARR[0]; +} diff --git a/gcc/testsuite/rust/compile/issue-3665.rs b/gcc/testsuite/rust/compile/issue-3665.rs new file mode 100644 index 0000000..d66a81f --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3665.rs @@ -0,0 +1,6 @@ +pub const uint_val: usize = 1; +pub const uint_expr: usize = 1 << uint_val; + +pub fn test() -> usize { + uint_expr +} diff --git a/gcc/testsuite/rust/compile/issue-3667.rs b/gcc/testsuite/rust/compile/issue-3667.rs new file mode 100644 index 0000000..e72069c --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3667.rs @@ -0,0 +1,24 @@ +// { dg-options "-w" } +#![feature(raw_ref_op)] + +const pq1: () = { + let mut x = 2; + &raw mut x; +}; //~ mutable reference + +static B: () = { + let mut x = 2; + &raw mut x; +}; //~ mutable reference + +static mut C: () = { + let mut x = 2; + &raw mut x; +}; //~ mutable reference + +const fn foo() { + let mut x = 0; + let y = &raw mut x; //~ mutable reference +} + +fn main() {} diff --git a/gcc/testsuite/rust/compile/issue-3671.rs b/gcc/testsuite/rust/compile/issue-3671.rs new file mode 100644 index 0000000..e800d53 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3671.rs @@ -0,0 +1,2 @@ +impl Self<0> {} +// { dg-error "could not resolve type path" "" { target *-*-* } .-1 } diff --git a/gcc/testsuite/rust/compile/issue-3711.rs b/gcc/testsuite/rust/compile/issue-3711.rs new file mode 100644 index 0000000..a3f9c39 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-3711.rs @@ -0,0 +1,17 @@ +#[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; +} + +fn returns_closure() -> _ { + // { dg-error "the type placeholder ._. is not allowed within types on item signatures .E0121." "" { target *-*-* } .-1 } + || 0 +} + +fn main() {} diff --git a/gcc/testsuite/rust/compile/issue-402.rs b/gcc/testsuite/rust/compile/issue-402.rs new file mode 100644 index 0000000..2c99fc8 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-402.rs @@ -0,0 +1,14 @@ +#[lang = "sized"] +pub trait Sized {} + +struct GenericStruct<T>(T, usize); + +pub fn test() -> GenericStruct<_> { + // { dg-error "the type placeholder ._. is not allowed within types on item signatures .E0121." "" { target *-*-* } .-1 } + GenericStruct(1, 2) +} + +fn square(num: i32) -> _ { + // { dg-error "the type placeholder ._. is not allowed within types on item signatures .E0121." "" { target *-*-* } .-1 } + num * num +} diff --git a/gcc/testsuite/rust/compile/iterators1.rs b/gcc/testsuite/rust/compile/iterators1.rs index 35fea5a..2ea3d74 100644 --- a/gcc/testsuite/rust/compile/iterators1.rs +++ b/gcc/testsuite/rust/compile/iterators1.rs @@ -98,30 +98,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); @@ -129,12 +129,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 } @@ -142,7 +142,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 @@ -151,31 +151,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); } } } @@ -190,7 +190,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); } } @@ -200,7 +200,7 @@ mod mem { } pub unsafe fn uninitialized<T>() -> T { - intrinsics::uninit() + crate::intrinsics::uninit() } } @@ -210,48 +210,30 @@ macro_rules! impl_uint { impl $ty { pub fn wrapping_add(self, rhs: Self) -> Self { unsafe { - intrinsics::wrapping_add(self, rhs) + crate::intrinsics::wrapping_add(self, rhs) } } pub fn wrapping_sub(self, rhs: Self) -> Self { unsafe { - intrinsics::wrapping_sub(self, rhs) + crate::intrinsics::wrapping_sub(self, rhs) } } pub fn rotate_left(self, n: u32) -> Self { unsafe { - intrinsics::rotate_left(self, n as Self) + crate::intrinsics::rotate_left(self, n as Self) } } pub fn rotate_right(self, n: u32) -> Self { unsafe { - intrinsics::rotate_right(self, n as Self) + crate::intrinsics::rotate_right(self, n as Self) } } - pub fn to_le(self) -> Self { - #[cfg(target_endian = "little")] - { - self - } - } - - pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self { - Self::from_le(Self::from_ne_bytes(bytes)) - } - - pub const fn from_le(x: Self) -> Self { - #[cfg(target_endian = "little")] - { - x - } - } - - pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self { - unsafe { mem::transmute(bytes) } + pub const fn from_ne_bytes(bytes: [u8; crate::mem::size_of::<Self>()]) -> Self { + unsafe { crate::mem::transmute(bytes) } } pub fn checked_add(self, rhs: Self) -> Option<Self> { @@ -264,7 +246,7 @@ macro_rules! impl_uint { } pub fn overflowing_add(self, rhs: Self) -> (Self, bool) { - let (a, b) = unsafe { intrinsics::add_with_overflow(self as $ty, rhs as $ty) }; + let (a, b) = unsafe { crate::intrinsics::add_with_overflow(self as $ty, rhs as $ty) }; (a as Self, b) } } @@ -380,12 +362,12 @@ macro_rules! step_identical_methods { () => { #[inline] fn replace_one(&mut self) -> Self { - mem::replace(self, 1) + crate::mem::replace(self, 1) } #[inline] fn replace_zero(&mut self) -> Self { - mem::replace(self, 0) + crate::mem::replace(self, 0) } #[inline] @@ -500,7 +482,7 @@ impl<A: Step> Iterator for Range<A> { // and this won't actually result in an extra check in an optimized build. match self.start.add_usize(1) { Option::Some(mut n) => { - mem::swap(&mut n, &mut self.start); + crate::mem::swap(&mut n, &mut self.start); Option::Some(n) } Option::None => Option::None, diff --git a/gcc/testsuite/rust/compile/macros/builtin/builtin_macro.exp b/gcc/testsuite/rust/compile/macros/builtin/builtin_macro.exp new file mode 100644 index 0000000..ac891db --- /dev/null +++ b/gcc/testsuite/rust/compile/macros/builtin/builtin_macro.exp @@ -0,0 +1,35 @@ +# 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/>. + +# Compile tests, no torture testing. +# +# These tests raise errors in the front end; torture testing doesn't apply. + +# 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 "compile" +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/compile/builtin_macro_compile_error.rs b/gcc/testsuite/rust/compile/macros/builtin/compile_error.rs index b08f67f..b08f67f 100644 --- a/gcc/testsuite/rust/compile/builtin_macro_compile_error.rs +++ b/gcc/testsuite/rust/compile/macros/builtin/compile_error.rs diff --git a/gcc/testsuite/rust/compile/builtin_macro_concat.rs b/gcc/testsuite/rust/compile/macros/builtin/concat.rs index 28c8424..28c8424 100644 --- a/gcc/testsuite/rust/compile/builtin_macro_concat.rs +++ b/gcc/testsuite/rust/compile/macros/builtin/concat.rs diff --git a/gcc/testsuite/rust/compile/builtin_macro_eager1.rs b/gcc/testsuite/rust/compile/macros/builtin/eager1.rs index 65a80fd..7c6f6f9 100644 --- a/gcc/testsuite/rust/compile/builtin_macro_eager1.rs +++ b/gcc/testsuite/rust/compile/macros/builtin/eager1.rs @@ -15,7 +15,7 @@ macro_rules! b { } fn main() { - // { dg-final { scan-tree-dump-times {"test1canary"} 1 gimple } } + // { dg-final { scan-assembler {"test1canary"} } } let _ = concat!(a!(), 1, b!()); // should not error concat!(a!(), true, b!(),); diff --git a/gcc/testsuite/rust/compile/builtin_macro_eager2.rs b/gcc/testsuite/rust/compile/macros/builtin/eager2.rs index 70a92d5..70a92d5 100644 --- a/gcc/testsuite/rust/compile/builtin_macro_eager2.rs +++ b/gcc/testsuite/rust/compile/macros/builtin/eager2.rs diff --git a/gcc/testsuite/rust/compile/builtin_macro_eager3.rs b/gcc/testsuite/rust/compile/macros/builtin/eager3.rs index 3b62cfe..3b62cfe 100644 --- a/gcc/testsuite/rust/compile/builtin_macro_eager3.rs +++ b/gcc/testsuite/rust/compile/macros/builtin/eager3.rs diff --git a/gcc/testsuite/rust/compile/builtin_macro_env.rs b/gcc/testsuite/rust/compile/macros/builtin/env.rs index 83d3c2d..83d3c2d 100644 --- a/gcc/testsuite/rust/compile/builtin_macro_env.rs +++ b/gcc/testsuite/rust/compile/macros/builtin/env.rs diff --git a/gcc/testsuite/rust/compile/macros/builtin/include1.rs b/gcc/testsuite/rust/compile/macros/builtin/include1.rs new file mode 100644 index 0000000..3ad64b7 --- /dev/null +++ b/gcc/testsuite/rust/compile/macros/builtin/include1.rs @@ -0,0 +1,14 @@ +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +macro_rules! include { + () => {}; +} + +include!("include_rs"); + +fn main() -> i32 { + b(); + + 0 +} diff --git a/gcc/testsuite/rust/compile/macros/builtin/include2.rs b/gcc/testsuite/rust/compile/macros/builtin/include2.rs new file mode 100644 index 0000000..d2344ac --- /dev/null +++ b/gcc/testsuite/rust/compile/macros/builtin/include2.rs @@ -0,0 +1,11 @@ +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +macro_rules! include { + () => {}; +} + +fn main() -> i32 { + let _ = include!("include_rs2"); + 0 +} diff --git a/gcc/testsuite/rust/compile/macros/builtin/include3.rs b/gcc/testsuite/rust/compile/macros/builtin/include3.rs new file mode 100644 index 0000000..62c0e52 --- /dev/null +++ b/gcc/testsuite/rust/compile/macros/builtin/include3.rs @@ -0,0 +1,19 @@ +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +macro_rules! include { + () => {}; +} + +macro_rules! my_file { + () => {"include_rs"}; +} + + +include!(my_file!()); + +fn main() -> i32 { + b(); + + 0 +} diff --git a/gcc/testsuite/rust/compile/macros/builtin/include4.rs b/gcc/testsuite/rust/compile/macros/builtin/include4.rs new file mode 100644 index 0000000..c2450fc --- /dev/null +++ b/gcc/testsuite/rust/compile/macros/builtin/include4.rs @@ -0,0 +1,15 @@ +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +macro_rules! include { + () => {}; +} + +macro_rules! my_file { + () => {"include_rs2"}; +} +fn main() -> i32 { + let _ = include!(my_file!()); + + 0 +} diff --git a/gcc/testsuite/rust/compile/macros/builtin/include_bytes.rs b/gcc/testsuite/rust/compile/macros/builtin/include_bytes.rs new file mode 100644 index 0000000..3ea2813 --- /dev/null +++ b/gcc/testsuite/rust/compile/macros/builtin/include_bytes.rs @@ -0,0 +1,23 @@ +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +macro_rules! include_bytes { + () => {{}}; +} + +macro_rules! file1 { + () => {"file"}; +} + +static MY_FILE: &[u32;16] = include_bytes!(file!()); + +fn main() { + let file = "include.txt"; + include_bytes!(file); // { dg-error "argument must be a string literal" "" } + include_bytes!(); // { dg-error "macro takes 1 argument" "" } + include_bytes!("foo.txt", "bar.txt"); // { dg-error "macro takes 1 argument" "" } + include_bytes!("include_bytes.rs"); // ok + include_bytes!("include_bytes.rs",); // trailing comma ok + include_bytes! (file1!()); + include_bytes! (file1!(),); // trailing comma ok +} diff --git a/gcc/testsuite/rust/compile/builtin_macro_include_bytes_location_info.rs b/gcc/testsuite/rust/compile/macros/builtin/include_bytes_location_info.rs index 98bf53b..98bf53b 100644 --- a/gcc/testsuite/rust/compile/builtin_macro_include_bytes_location_info.rs +++ b/gcc/testsuite/rust/compile/macros/builtin/include_bytes_location_info.rs diff --git a/gcc/testsuite/rust/compile/macros/builtin/include_rs b/gcc/testsuite/rust/compile/macros/builtin/include_rs new file mode 100644 index 0000000..77c3e26 --- /dev/null +++ b/gcc/testsuite/rust/compile/macros/builtin/include_rs @@ -0,0 +1 @@ +fn b() {} diff --git a/gcc/testsuite/rust/compile/macros/builtin/include_rs2 b/gcc/testsuite/rust/compile/macros/builtin/include_rs2 new file mode 100644 index 0000000..31b272a --- /dev/null +++ b/gcc/testsuite/rust/compile/macros/builtin/include_rs2 @@ -0,0 +1 @@ +"Gccrs is GREAT!" diff --git a/gcc/testsuite/rust/compile/macros/builtin/include_str.rs b/gcc/testsuite/rust/compile/macros/builtin/include_str.rs new file mode 100644 index 0000000..eda04ac --- /dev/null +++ b/gcc/testsuite/rust/compile/macros/builtin/include_str.rs @@ -0,0 +1,24 @@ +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +macro_rules! include_str { + () => {{}}; +} + +macro_rules! my_file { + () => {"include.txt"} +} + +static G_STR:[u8;16] = include_str!(my_file!()); + +fn main() { + let file = "include.txt"; + include_str!(file); // { dg-error "argument must be a string literal" "" } + include_str!(); // { dg-error "macro takes 1 argument" "" } + include_str!("foo.txt", "bar.txt"); // { dg-error "macro takes 1 argument" "" } + include_str!("include_str.rs"); // ok + include_str!("include_str.rs",); // trailing comma ok + include_str!("invalid_utf8"); // { dg-error "invalid_utf8 was not a valid utf-8 file" "" } + include_str!(my_file!()); + include_str!(my_file!(),); +} diff --git a/gcc/testsuite/rust/compile/builtin_macro_include_str_location_info.rs b/gcc/testsuite/rust/compile/macros/builtin/include_str_location_info.rs index a946033..a946033 100644 --- a/gcc/testsuite/rust/compile/builtin_macro_include_str_location_info.rs +++ b/gcc/testsuite/rust/compile/macros/builtin/include_str_location_info.rs diff --git a/gcc/testsuite/rust/compile/invalid_utf8 b/gcc/testsuite/rust/compile/macros/builtin/invalid_utf8 index 29e181e..29e181e 100644 --- a/gcc/testsuite/rust/compile/invalid_utf8 +++ b/gcc/testsuite/rust/compile/macros/builtin/invalid_utf8 diff --git a/gcc/testsuite/rust/compile/builtin_macro_not_found.rs b/gcc/testsuite/rust/compile/macros/builtin/not_found.rs index 5ba7fc0..5ba7fc0 100644 --- a/gcc/testsuite/rust/compile/builtin_macro_not_found.rs +++ b/gcc/testsuite/rust/compile/macros/builtin/not_found.rs diff --git a/gcc/testsuite/rust/compile/macros/builtin/option_env1.rs b/gcc/testsuite/rust/compile/macros/builtin/option_env1.rs new file mode 100644 index 0000000..cf9f65b --- /dev/null +++ b/gcc/testsuite/rust/compile/macros/builtin/option_env1.rs @@ -0,0 +1,29 @@ +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +macro_rules! option_env { + () => {} +} + +#[lang = "sized"] +trait Sized {} + +pub mod core { + pub mod option { + pub enum Option<T> { + #[lang = "Some"] + Some(T), + #[lang = "None"] + None, + } + } +} + +use core::option::Option; + + +fn main() { + // Both a guaranteed-to-exist variable and a failed find should compile + let _: Option<&str> = option_env!("PWD"); + let _: Option<&str> = option_env!("PROBABLY_DOESNT_EXIST"); +} diff --git a/gcc/testsuite/rust/compile/macros/builtin/option_env2.rs b/gcc/testsuite/rust/compile/macros/builtin/option_env2.rs new file mode 100644 index 0000000..63f7254 --- /dev/null +++ b/gcc/testsuite/rust/compile/macros/builtin/option_env2.rs @@ -0,0 +1,27 @@ +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +macro_rules! option_env { + () => {} +} + +#[lang = "sized"] +trait Sized {} + +pub mod core { + pub mod option { + pub enum Option<T> { + #[lang = "Some"] + Some(T), + #[lang = "None"] + None, + } + } +} + +use core::option::Option; + +fn main() { + let _: Option<&str> = option_env!(42); + // { dg-error "argument must be a string literal" "" { target *-*-* } .-1 } +} diff --git a/gcc/testsuite/rust/compile/macros/builtin/option_env3.rs b/gcc/testsuite/rust/compile/macros/builtin/option_env3.rs new file mode 100644 index 0000000..ad6dd4c --- /dev/null +++ b/gcc/testsuite/rust/compile/macros/builtin/option_env3.rs @@ -0,0 +1,28 @@ +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +macro_rules! option_env { + () => {} +} + +#[lang = "sized"] +trait Sized {} + +pub mod core { + pub mod option { + pub enum Option<T> { + #[lang = "Some"] + Some(T), + #[lang = "None"] + None, + } + } +} + +use core::option::Option; + + +fn main() { + let _: Option<&str> = option_env!("A","B"); + // { dg-error "'option_env!' takes 1 argument" "" { target *-*-* } .-1 } +} diff --git a/gcc/testsuite/rust/compile/macros/builtin/recurse2.rs b/gcc/testsuite/rust/compile/macros/builtin/recurse2.rs new file mode 100644 index 0000000..73e6ab4 --- /dev/null +++ b/gcc/testsuite/rust/compile/macros/builtin/recurse2.rs @@ -0,0 +1,43 @@ +// { dg-additional-options "-fdump-tree-gimple" } +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +macro_rules! concat { + () => {}; +} + +macro_rules! a { + () => { + "hey" + }; + ($($t:tt)*) => { + "ho" + }; +} + +extern "C" { + fn printf(fmt: *const i8, ...); +} + +fn print_ptr(s: &str) { + unsafe { + printf("%p\n\0" as *const str as *const i8, s as *const str); + } +} + +fn print_str(s: &str) { + unsafe { + printf( + "%s\n\0" as *const str as *const i8, + s as *const str as *const i8, + ); + } +} + +// { dg-final { scan-assembler {"abheyho"} } } +static S: &str = concat!("a", 'b', a!(), a!(b c d e f a!()), '\0'); + +fn main() { + print_ptr(S); + print_str(S); +} diff --git a/gcc/testsuite/rust/compile/macro-delim.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-delim.rs index de4cd56..de4cd56 100644 --- a/gcc/testsuite/rust/compile/macro-delim.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-delim.rs diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-expand-module.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-expand-module.rs new file mode 100644 index 0000000..e3e702e --- /dev/null +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-expand-module.rs @@ -0,0 +1,11 @@ +mod foo { + macro_rules! bar { + () => () + } + + bar! (); + + pub struct S; +} + +pub fn buzz(_: foo::S) {} diff --git a/gcc/testsuite/rust/compile/macro-issue1053-2.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue1053-2.rs index 3145990..3145990 100644 --- a/gcc/testsuite/rust/compile/macro-issue1053-2.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue1053-2.rs diff --git a/gcc/testsuite/rust/compile/macro-issue1053.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue1053.rs index 1e96849..1e96849 100644 --- a/gcc/testsuite/rust/compile/macro-issue1053.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue1053.rs diff --git a/gcc/testsuite/rust/compile/macro-issue1224.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue1224.rs index 003bbcd..003bbcd 100644 --- a/gcc/testsuite/rust/compile/macro-issue1224.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue1224.rs diff --git a/gcc/testsuite/rust/compile/macro-issue1233.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue1233.rs index 7fab787..7fab787 100644 --- a/gcc/testsuite/rust/compile/macro-issue1233.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue1233.rs diff --git a/gcc/testsuite/rust/compile/macro-issue1395-2.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue1395-2.rs index 1df6a3a..1df6a3a 100644 --- a/gcc/testsuite/rust/compile/macro-issue1395-2.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue1395-2.rs diff --git a/gcc/testsuite/rust/compile/macro-issue1395.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue1395.rs index b0368c1..b0368c1 100644 --- a/gcc/testsuite/rust/compile/macro-issue1395.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue1395.rs diff --git a/gcc/testsuite/rust/compile/macro-issue1400-2.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue1400-2.rs index ba7b61b..ba7b61b 100644 --- a/gcc/testsuite/rust/compile/macro-issue1400-2.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue1400-2.rs diff --git a/gcc/testsuite/rust/compile/macro-issue1400.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue1400.rs index 5c51b78..5c51b78 100644 --- a/gcc/testsuite/rust/compile/macro-issue1400.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue1400.rs diff --git a/gcc/testsuite/rust/compile/macro-issue2092.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue2092.rs index ec20743..ec20743 100644 --- a/gcc/testsuite/rust/compile/macro-issue2092.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue2092.rs diff --git a/gcc/testsuite/rust/compile/macro-issue2192.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue2192.rs index deb2dd7..deb2dd7 100644 --- a/gcc/testsuite/rust/compile/macro-issue2192.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue2192.rs diff --git a/gcc/testsuite/rust/compile/macro-issue2194.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue2194.rs index c94b114..c94b114 100644 --- a/gcc/testsuite/rust/compile/macro-issue2194.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue2194.rs diff --git a/gcc/testsuite/rust/compile/macro-issue2229.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue2229.rs index c148ff5..c148ff5 100644 --- a/gcc/testsuite/rust/compile/macro-issue2229.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue2229.rs diff --git a/gcc/testsuite/rust/compile/macro-issue2264.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue2264.rs index 497dd3c..497dd3c 100644 --- a/gcc/testsuite/rust/compile/macro-issue2264.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue2264.rs diff --git a/gcc/testsuite/rust/compile/macro-issue2268.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue2268.rs index 4bd9c10..4bd9c10 100644 --- a/gcc/testsuite/rust/compile/macro-issue2268.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue2268.rs diff --git a/gcc/testsuite/rust/compile/macro-issue2273.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue2273.rs index ee3dd1f..ee3dd1f 100644 --- a/gcc/testsuite/rust/compile/macro-issue2273.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue2273.rs diff --git a/gcc/testsuite/rust/compile/macro-issue2653.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue2653.rs index dc2972f..dc2972f 100644 --- a/gcc/testsuite/rust/compile/macro-issue2653.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue2653.rs diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue2983_2984.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue2983_2984.rs new file mode 100644 index 0000000..eeae6eb --- /dev/null +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue2983_2984.rs @@ -0,0 +1,26 @@ +pub struct ReadDir { + pub inner: i32, + #[cfg(not(A))] + pub end_of_stream: bool, + #[cfg(A)] + pub end_of_stream_but_different: bool, +} + +fn main() { + // Success + let _ = ReadDir { + inner: 14, + #[cfg(not(A))] + end_of_stream: false, + #[cfg(A)] + end_of_stream_but_different: false, + }; + + // Error + let _ = ReadDir { + // { dg-error "unknown field .end_of_stream_but_different. .E0560." "" { target *-*-* } .-1 } + inner: 14, + end_of_stream: false, + end_of_stream_but_different: false, + }; +} diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue3693.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3693.rs new file mode 100644 index 0000000..e990c8b --- /dev/null +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3693.rs @@ -0,0 +1,10 @@ +macro_rules! generate_pattern_iterators { + { + $(#[$forward_iterator_attribute:meta])* + } => { + } +} + +generate_pattern_iterators! { + /// Created with the method [`split`]. +} diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs new file mode 100644 index 0000000..e5b38bb --- /dev/null +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs @@ -0,0 +1,80 @@ +// { dg-additional-options "-frust-name-resolution-2.0 -frust-compile-until=lowering" } + +macro_rules! impl_fn_for_zst { + ($( + $( #[$attr: meta] )* + struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn = + |$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty + $body: block; + )+) => { + $( + $( #[$attr] )* + struct $Name; + + impl $( <$( $lifetime ),+> )? Fn<($( $ArgTy, )*)> for $Name { + #[inline] + extern "rust-call" fn call(&self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy { + $body + } + } + + impl $( <$( $lifetime ),+> )? FnMut<($( $ArgTy, )*)> for $Name { + #[inline] + extern "rust-call" fn call_mut( + &mut self, + ($( $arg, )*): ($( $ArgTy, )*) + ) -> $ReturnTy { + Fn::call(&*self, ($( $arg, )*)) + } + } + + impl $( <$( $lifetime ),+> )? FnOnce<($( $ArgTy, )*)> for $Name { + type Output = $ReturnTy; + + #[inline] + extern "rust-call" fn call_once(self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy { + Fn::call(&self, ($( $arg, )*)) + } + } + )+ + } +} + +#[lang = "sized"] +trait Sized {} + +#[lang = "copy"] +trait Copy {} + +#[lang = "fn"] +pub trait Fn<Args>: FnMut<Args> { + /// Performs the call operation. + #[unstable(feature = "fn_traits", issue = "29625")] + extern "rust-call" fn call(&self, args: Args) -> Self::Output; +} + +#[lang = "fn_mut"] +#[must_use = "closures are lazy and do nothing unless called"] +pub trait FnMut<Args>: FnOnce<Args> { + /// Performs the call operation. + #[unstable(feature = "fn_traits", issue = "29625")] + extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output; +} + +#[lang = "fn_once"] +pub trait FnOnce<Args> { + /// The returned type after the call operator is used. + #[lang = "fn_once_output"] + #[stable(feature = "fn_once_output", since = "1.12.0")] + type Output; + + /// Performs the call operation. + #[unstable(feature = "fn_traits", issue = "29625")] + extern "rust-call" fn call_once(self, args: Args) -> Self::Output; +} + +impl_fn_for_zst! { + #[derive(Copy)] + struct LinesAnyMap impl<'a> Fn = |line: &'a str| -> () { + }; +} diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-1.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-1.rs new file mode 100644 index 0000000..6fc3a31 --- /dev/null +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-1.rs @@ -0,0 +1,10 @@ +macro_rules! doc_comment { + (#[ $attr: meta ]) => { + #[$attr] + struct Generated; // { dg-warning "never constructed" } + }; +} + +doc_comment! { + /// This is a generated struct +} diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-2.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-2.rs new file mode 100644 index 0000000..cfc8ab4 --- /dev/null +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-2.rs @@ -0,0 +1,81 @@ +// { dg-additional-options "-frust-name-resolution-2.0 -frust-compile-until=lowering" } + +macro_rules! impl_fn_for_zst { + ($( + $( #[$attr: meta] )* + struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn = + |$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty + $body: block; + )+) => { + $( + $( #[$attr] )* + struct $Name; + + impl $( <$( $lifetime ),+> )? Fn<($( $ArgTy, )*)> for $Name { + #[inline] + extern "rust-call" fn call(&self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy { + $body + } + } + + impl $( <$( $lifetime ),+> )? FnMut<($( $ArgTy, )*)> for $Name { + #[inline] + extern "rust-call" fn call_mut( + &mut self, + ($( $arg, )*): ($( $ArgTy, )*) + ) -> $ReturnTy { + Fn::call(&*self, ($( $arg, )*)) + } + } + + impl $( <$( $lifetime ),+> )? FnOnce<($( $ArgTy, )*)> for $Name { + type Output = $ReturnTy; + + #[inline] + extern "rust-call" fn call_once(self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy { + Fn::call(&self, ($( $arg, )*)) + } + } + )+ + } +} + +#[lang = "sized"] +trait Sized {} + +#[lang = "copy"] +trait Copy {} + +#[lang = "fn"] +pub trait Fn<Args>: FnMut<Args> { + /// Performs the call operation. + #[unstable(feature = "fn_traits", issue = "29625")] + extern "rust-call" fn call(&self, args: Args) -> Self::Output; +} + +#[lang = "fn_mut"] +#[must_use = "closures are lazy and do nothing unless called"] +pub trait FnMut<Args>: FnOnce<Args> { + /// Performs the call operation. + #[unstable(feature = "fn_traits", issue = "29625")] + extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output; +} + +#[lang = "fn_once"] +pub trait FnOnce<Args> { + /// The returned type after the call operator is used. + #[lang = "fn_once_output"] + #[stable(feature = "fn_once_output", since = "1.12.0")] + type Output; + + /// Performs the call operation. + #[unstable(feature = "fn_traits", issue = "29625")] + extern "rust-call" fn call_once(self, args: Args) -> Self::Output; +} + +impl_fn_for_zst! { + /// Documentation for the zst + #[derive(Copy)] + struct LinesAnyMap impl<'a> Fn = |line: &'a str| -> () { + }; +} diff --git a/gcc/testsuite/rust/compile/macro1.rs b/gcc/testsuite/rust/compile/macros/mbe/macro1.rs index 8cd9418..8cd9418 100644 --- a/gcc/testsuite/rust/compile/macro1.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro1.rs diff --git a/gcc/testsuite/rust/compile/macro10.rs b/gcc/testsuite/rust/compile/macros/mbe/macro10.rs index 3f1453e..3f1453e 100644 --- a/gcc/testsuite/rust/compile/macro10.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro10.rs diff --git a/gcc/testsuite/rust/compile/macro11.rs b/gcc/testsuite/rust/compile/macros/mbe/macro11.rs index 97b89a1..97b89a1 100644 --- a/gcc/testsuite/rust/compile/macro11.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro11.rs diff --git a/gcc/testsuite/rust/compile/macro12.rs b/gcc/testsuite/rust/compile/macros/mbe/macro12.rs index b75fbad..b75fbad 100644 --- a/gcc/testsuite/rust/compile/macro12.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro12.rs diff --git a/gcc/testsuite/rust/compile/macro13.rs b/gcc/testsuite/rust/compile/macros/mbe/macro13.rs index eb8dfbb..eb8dfbb 100644 --- a/gcc/testsuite/rust/compile/macro13.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro13.rs diff --git a/gcc/testsuite/rust/compile/macro14.rs b/gcc/testsuite/rust/compile/macros/mbe/macro14.rs index b18c56e..b18c56e 100644 --- a/gcc/testsuite/rust/compile/macro14.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro14.rs diff --git a/gcc/testsuite/rust/compile/macro15.rs b/gcc/testsuite/rust/compile/macros/mbe/macro15.rs index 02c739e..02c739e 100644 --- a/gcc/testsuite/rust/compile/macro15.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro15.rs diff --git a/gcc/testsuite/rust/compile/macro16.rs b/gcc/testsuite/rust/compile/macros/mbe/macro16.rs index e5e56ed..e5e56ed 100644 --- a/gcc/testsuite/rust/compile/macro16.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro16.rs diff --git a/gcc/testsuite/rust/compile/macro17.rs b/gcc/testsuite/rust/compile/macros/mbe/macro17.rs index b50afbe..b50afbe 100644 --- a/gcc/testsuite/rust/compile/macro17.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro17.rs diff --git a/gcc/testsuite/rust/compile/macro18.rs b/gcc/testsuite/rust/compile/macros/mbe/macro18.rs index 5418725..5418725 100644 --- a/gcc/testsuite/rust/compile/macro18.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro18.rs diff --git a/gcc/testsuite/rust/compile/macro19.rs b/gcc/testsuite/rust/compile/macros/mbe/macro19.rs index 1bf9a2b..1bf9a2b 100644 --- a/gcc/testsuite/rust/compile/macro19.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro19.rs diff --git a/gcc/testsuite/rust/compile/macro2.rs b/gcc/testsuite/rust/compile/macros/mbe/macro2.rs index a437655..a437655 100644 --- a/gcc/testsuite/rust/compile/macro2.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro2.rs diff --git a/gcc/testsuite/rust/compile/macro20.rs b/gcc/testsuite/rust/compile/macros/mbe/macro20.rs index e03455b..e03455b 100644 --- a/gcc/testsuite/rust/compile/macro20.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro20.rs diff --git a/gcc/testsuite/rust/compile/macro21.rs b/gcc/testsuite/rust/compile/macros/mbe/macro21.rs index 9a1d773..9a1d773 100644 --- a/gcc/testsuite/rust/compile/macro21.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro21.rs diff --git a/gcc/testsuite/rust/compile/macro22.rs b/gcc/testsuite/rust/compile/macros/mbe/macro22.rs index bdc4bad..bdc4bad 100644 --- a/gcc/testsuite/rust/compile/macro22.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro22.rs diff --git a/gcc/testsuite/rust/compile/macro23.rs b/gcc/testsuite/rust/compile/macros/mbe/macro23.rs index a6a2afd..a6a2afd 100644 --- a/gcc/testsuite/rust/compile/macro23.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro23.rs diff --git a/gcc/testsuite/rust/compile/macro25.rs b/gcc/testsuite/rust/compile/macros/mbe/macro25.rs index d92534c..d92534c 100644 --- a/gcc/testsuite/rust/compile/macro25.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro25.rs diff --git a/gcc/testsuite/rust/compile/macro26.rs b/gcc/testsuite/rust/compile/macros/mbe/macro26.rs index f6588e7..f6588e7 100644 --- a/gcc/testsuite/rust/compile/macro26.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro26.rs diff --git a/gcc/testsuite/rust/compile/macro27.rs b/gcc/testsuite/rust/compile/macros/mbe/macro27.rs index ee7833b..ee7833b 100644 --- a/gcc/testsuite/rust/compile/macro27.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro27.rs diff --git a/gcc/testsuite/rust/compile/macro28.rs b/gcc/testsuite/rust/compile/macros/mbe/macro28.rs index 8002f28..8002f28 100644 --- a/gcc/testsuite/rust/compile/macro28.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro28.rs diff --git a/gcc/testsuite/rust/compile/macro29.rs b/gcc/testsuite/rust/compile/macros/mbe/macro29.rs index 39f5021..39f5021 100644 --- a/gcc/testsuite/rust/compile/macro29.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro29.rs diff --git a/gcc/testsuite/rust/compile/macro3.rs b/gcc/testsuite/rust/compile/macros/mbe/macro3.rs index e5d3e93..e5d3e93 100644 --- a/gcc/testsuite/rust/compile/macro3.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro3.rs diff --git a/gcc/testsuite/rust/compile/macro30.rs b/gcc/testsuite/rust/compile/macros/mbe/macro30.rs index 35064bc0..35064bc0 100644 --- a/gcc/testsuite/rust/compile/macro30.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro30.rs diff --git a/gcc/testsuite/rust/compile/macro31.rs b/gcc/testsuite/rust/compile/macros/mbe/macro31.rs index 6674a5f..6674a5f 100644 --- a/gcc/testsuite/rust/compile/macro31.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro31.rs diff --git a/gcc/testsuite/rust/compile/macro32.rs b/gcc/testsuite/rust/compile/macros/mbe/macro32.rs index d1d6305..d1d6305 100644 --- a/gcc/testsuite/rust/compile/macro32.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro32.rs diff --git a/gcc/testsuite/rust/compile/macro33.rs b/gcc/testsuite/rust/compile/macros/mbe/macro33.rs index 2ccd33e..2ccd33e 100644 --- a/gcc/testsuite/rust/compile/macro33.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro33.rs diff --git a/gcc/testsuite/rust/compile/macro34.rs b/gcc/testsuite/rust/compile/macros/mbe/macro34.rs index 105d042..105d042 100644 --- a/gcc/testsuite/rust/compile/macro34.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro34.rs diff --git a/gcc/testsuite/rust/compile/macro35.rs b/gcc/testsuite/rust/compile/macros/mbe/macro35.rs index 07b157b..07b157b 100644 --- a/gcc/testsuite/rust/compile/macro35.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro35.rs diff --git a/gcc/testsuite/rust/compile/macro36.rs b/gcc/testsuite/rust/compile/macros/mbe/macro36.rs index e5d66b2..e5d66b2 100644 --- a/gcc/testsuite/rust/compile/macro36.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro36.rs diff --git a/gcc/testsuite/rust/compile/macro37.rs b/gcc/testsuite/rust/compile/macros/mbe/macro37.rs index 5713d90..5713d90 100644 --- a/gcc/testsuite/rust/compile/macro37.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro37.rs diff --git a/gcc/testsuite/rust/compile/macro38.rs b/gcc/testsuite/rust/compile/macros/mbe/macro38.rs index eb294ae..eb294ae 100644 --- a/gcc/testsuite/rust/compile/macro38.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro38.rs diff --git a/gcc/testsuite/rust/compile/macro39.rs b/gcc/testsuite/rust/compile/macros/mbe/macro39.rs index f5c498c..f5c498c 100644 --- a/gcc/testsuite/rust/compile/macro39.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro39.rs diff --git a/gcc/testsuite/rust/compile/macro4.rs b/gcc/testsuite/rust/compile/macros/mbe/macro4.rs index 47ff6c9..47ff6c9 100644 --- a/gcc/testsuite/rust/compile/macro4.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro4.rs diff --git a/gcc/testsuite/rust/compile/macro40.rs b/gcc/testsuite/rust/compile/macros/mbe/macro40.rs index f9d048e..f9d048e 100644 --- a/gcc/testsuite/rust/compile/macro40.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro40.rs diff --git a/gcc/testsuite/rust/compile/macro41.rs b/gcc/testsuite/rust/compile/macros/mbe/macro41.rs index 3824422..3824422 100644 --- a/gcc/testsuite/rust/compile/macro41.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro41.rs diff --git a/gcc/testsuite/rust/compile/macro42.rs b/gcc/testsuite/rust/compile/macros/mbe/macro42.rs index b3fbf6d..b3fbf6d 100644 --- a/gcc/testsuite/rust/compile/macro42.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro42.rs diff --git a/gcc/testsuite/rust/compile/macro43.rs b/gcc/testsuite/rust/compile/macros/mbe/macro43.rs index 992bc77..0a7f038 100644 --- a/gcc/testsuite/rust/compile/macro43.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro43.rs @@ -1,3 +1,10 @@ +use Option::{None, Some}; + +enum Option<T> { + None, + Some(T) +} + macro_rules! nonzero_integers { ( $( $Ty: ident($Int: ty); )+ ) => { $( @@ -14,7 +21,7 @@ macro_rules! nonzero_integers { // not all derive macros are implemented yet, and this test does not test these anyways // #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[repr(transparent)] - pub struct $Ty(NonZero<$Int>); + pub struct $Ty($Int); impl $Ty { /// Create a non-zero without checking the value. @@ -25,7 +32,7 @@ macro_rules! nonzero_integers { #[stable(feature = "nonzero", since = "1.28.0")] #[inline] pub const unsafe fn new_unchecked(n: $Int) -> Self { - $Ty(NonZero(n)) + $Ty(n) } /// Create a non-zero if the given value is not zero. @@ -33,7 +40,7 @@ macro_rules! nonzero_integers { #[inline] pub fn new(n: $Int) -> Option<Self> { if n != 0 { - Some($Ty(NonZero(n))) + Some($Ty(n)) } else { None } @@ -43,12 +50,12 @@ macro_rules! nonzero_integers { #[stable(feature = "nonzero", since = "1.28.0")] #[inline] pub fn get(self) -> $Int { - self.0 .0 + self.0 } } - impl_nonzero_fmt! { // { dg-error "unknown macro" } + impl_nonzero_fmt! { // { dg-error "could not resolve macro invocation" } (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty } )+ diff --git a/gcc/testsuite/rust/compile/macro44.rs b/gcc/testsuite/rust/compile/macros/mbe/macro44.rs index dabac6f..0cfd987 100644 --- a/gcc/testsuite/rust/compile/macro44.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro44.rs @@ -16,7 +16,7 @@ mod foo { } fn bar_f() { - baz!(); // { dg-error "unknown macro" } + baz!(); // { dg-error "could not resolve macro invocation" } } } diff --git a/gcc/testsuite/rust/compile/macro45.rs b/gcc/testsuite/rust/compile/macros/mbe/macro45.rs index 52dbcbb..52dbcbb 100644 --- a/gcc/testsuite/rust/compile/macro45.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro45.rs diff --git a/gcc/testsuite/rust/compile/macro46.rs b/gcc/testsuite/rust/compile/macros/mbe/macro46.rs index 3ef811a..3ef811a 100644 --- a/gcc/testsuite/rust/compile/macro46.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro46.rs diff --git a/gcc/testsuite/rust/compile/macro47.rs b/gcc/testsuite/rust/compile/macros/mbe/macro47.rs index 36545af..36545af 100644 --- a/gcc/testsuite/rust/compile/macro47.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro47.rs diff --git a/gcc/testsuite/rust/compile/macro48.rs b/gcc/testsuite/rust/compile/macros/mbe/macro48.rs index 6b3b369..6b3b369 100644 --- a/gcc/testsuite/rust/compile/macro48.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro48.rs diff --git a/gcc/testsuite/rust/compile/macro49.rs b/gcc/testsuite/rust/compile/macros/mbe/macro49.rs index 0900f7c..0900f7c 100644 --- a/gcc/testsuite/rust/compile/macro49.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro49.rs diff --git a/gcc/testsuite/rust/compile/macro5.rs b/gcc/testsuite/rust/compile/macros/mbe/macro5.rs index a5d8095..a5d8095 100644 --- a/gcc/testsuite/rust/compile/macro5.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro5.rs diff --git a/gcc/testsuite/rust/compile/macro50.rs b/gcc/testsuite/rust/compile/macros/mbe/macro50.rs index e85afa7..e85afa7 100644 --- a/gcc/testsuite/rust/compile/macro50.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro50.rs diff --git a/gcc/testsuite/rust/compile/macro51.rs b/gcc/testsuite/rust/compile/macros/mbe/macro51.rs index 6659486..6659486 100644 --- a/gcc/testsuite/rust/compile/macro51.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro51.rs diff --git a/gcc/testsuite/rust/compile/macro52.rs b/gcc/testsuite/rust/compile/macros/mbe/macro52.rs index 31002eb..31002eb 100644 --- a/gcc/testsuite/rust/compile/macro52.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro52.rs diff --git a/gcc/testsuite/rust/compile/macro53.rs b/gcc/testsuite/rust/compile/macros/mbe/macro53.rs index efa2d4b..efa2d4b 100644 --- a/gcc/testsuite/rust/compile/macro53.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro53.rs diff --git a/gcc/testsuite/rust/compile/macro54.rs b/gcc/testsuite/rust/compile/macros/mbe/macro54.rs index d3b3f80..d3b3f80 100644 --- a/gcc/testsuite/rust/compile/macro54.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro54.rs diff --git a/gcc/testsuite/rust/compile/macro55.rs b/gcc/testsuite/rust/compile/macros/mbe/macro55.rs index 808718c..808718c 100644 --- a/gcc/testsuite/rust/compile/macro55.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro55.rs diff --git a/gcc/testsuite/rust/compile/macro56.rs b/gcc/testsuite/rust/compile/macros/mbe/macro56.rs index bf42a64..bf42a64 100644 --- a/gcc/testsuite/rust/compile/macro56.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro56.rs diff --git a/gcc/testsuite/rust/compile/macro57.rs b/gcc/testsuite/rust/compile/macros/mbe/macro57.rs index 0640d2f..0640d2f 100644 --- a/gcc/testsuite/rust/compile/macro57.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro57.rs diff --git a/gcc/testsuite/rust/compile/macro6.rs b/gcc/testsuite/rust/compile/macros/mbe/macro6.rs index 9c54a67..bbaaa25 100644 --- a/gcc/testsuite/rust/compile/macro6.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro6.rs @@ -1,6 +1,6 @@ macro_rules! zero_or_one { ($($a:literal)?) => { - f(); + 1 + 2; } } diff --git a/gcc/testsuite/rust/compile/macro7.rs b/gcc/testsuite/rust/compile/macros/mbe/macro7.rs index 563acdd..563acdd 100644 --- a/gcc/testsuite/rust/compile/macro7.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro7.rs diff --git a/gcc/testsuite/rust/compile/macro8.rs b/gcc/testsuite/rust/compile/macros/mbe/macro8.rs index d3e8af9..d3e8af9 100644 --- a/gcc/testsuite/rust/compile/macro8.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro8.rs diff --git a/gcc/testsuite/rust/compile/macro9.rs b/gcc/testsuite/rust/compile/macros/mbe/macro9.rs index 9a59089..9a59089 100644 --- a/gcc/testsuite/rust/compile/macro9.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro9.rs diff --git a/gcc/testsuite/rust/compile/macro_call_statement.rs b/gcc/testsuite/rust/compile/macros/mbe/macro_call_statement.rs index 3d18cc9..3d18cc9 100644 --- a/gcc/testsuite/rust/compile/macro_call_statement.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro_call_statement.rs diff --git a/gcc/testsuite/rust/compile/macro_export_1.rs b/gcc/testsuite/rust/compile/macros/mbe/macro_export_1.rs index f87df08..f87df08 100644 --- a/gcc/testsuite/rust/compile/macro_export_1.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro_export_1.rs diff --git a/gcc/testsuite/rust/compile/macro_return.rs b/gcc/testsuite/rust/compile/macros/mbe/macro_return.rs index 8b06f87..8b06f87 100644 --- a/gcc/testsuite/rust/compile/macro_return.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro_return.rs diff --git a/gcc/testsuite/rust/compile/macro_rules_macro_rules.rs b/gcc/testsuite/rust/compile/macros/mbe/macro_rules_macro_rules.rs index ecd1712..ecd1712 100644 --- a/gcc/testsuite/rust/compile/macro_rules_macro_rules.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro_rules_macro_rules.rs diff --git a/gcc/testsuite/rust/compile/macro_use1.rs b/gcc/testsuite/rust/compile/macros/mbe/macro_use1.rs index e98eadf..e98eadf 100644 --- a/gcc/testsuite/rust/compile/macro_use1.rs +++ b/gcc/testsuite/rust/compile/macros/mbe/macro_use1.rs diff --git a/gcc/testsuite/rust/compile/macros/mbe/mbe_macro.exp b/gcc/testsuite/rust/compile/macros/mbe/mbe_macro.exp new file mode 100644 index 0000000..ac891db --- /dev/null +++ b/gcc/testsuite/rust/compile/macros/mbe/mbe_macro.exp @@ -0,0 +1,35 @@ +# 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/>. + +# Compile tests, no torture testing. +# +# These tests raise errors in the front end; torture testing doesn't apply. + +# 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 "compile" +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/compile/proc_macro_attribute_crate_type.rs b/gcc/testsuite/rust/compile/macros/proc/attribute_crate_type.rs index c13128e..c13128e 100644 --- a/gcc/testsuite/rust/compile/proc_macro_attribute_crate_type.rs +++ b/gcc/testsuite/rust/compile/macros/proc/attribute_crate_type.rs diff --git a/gcc/testsuite/rust/compile/proc_macro_attribute_non_function.rs b/gcc/testsuite/rust/compile/macros/proc/attribute_non_function.rs index 0e88bbe..0e88bbe 100644 --- a/gcc/testsuite/rust/compile/proc_macro_attribute_non_function.rs +++ b/gcc/testsuite/rust/compile/macros/proc/attribute_non_function.rs diff --git a/gcc/testsuite/rust/compile/proc_macro_attribute_non_root_function.rs b/gcc/testsuite/rust/compile/macros/proc/attribute_non_root_function.rs index 709119c..709119c 100644 --- a/gcc/testsuite/rust/compile/proc_macro_attribute_non_root_function.rs +++ b/gcc/testsuite/rust/compile/macros/proc/attribute_non_root_function.rs diff --git a/gcc/testsuite/rust/compile/proc_macro_attribute_non_root_method.rs b/gcc/testsuite/rust/compile/macros/proc/attribute_non_root_method.rs index 30f3196..30f3196 100644 --- a/gcc/testsuite/rust/compile/proc_macro_attribute_non_root_method.rs +++ b/gcc/testsuite/rust/compile/macros/proc/attribute_non_root_method.rs diff --git a/gcc/testsuite/rust/compile/proc_macro_attribute_non_root_module.rs b/gcc/testsuite/rust/compile/macros/proc/attribute_non_root_module.rs index 60165be..60165be 100644 --- a/gcc/testsuite/rust/compile/proc_macro_attribute_non_root_module.rs +++ b/gcc/testsuite/rust/compile/macros/proc/attribute_non_root_module.rs diff --git a/gcc/testsuite/rust/compile/proc_macro_attribute_private.rs b/gcc/testsuite/rust/compile/macros/proc/attribute_private.rs index 00b5ac6..00b5ac6 100644 --- a/gcc/testsuite/rust/compile/proc_macro_attribute_private.rs +++ b/gcc/testsuite/rust/compile/macros/proc/attribute_private.rs diff --git a/gcc/testsuite/rust/compile/proc_macro_crate_type.rs b/gcc/testsuite/rust/compile/macros/proc/crate_type.rs index 880026d..880026d 100644 --- a/gcc/testsuite/rust/compile/proc_macro_crate_type.rs +++ b/gcc/testsuite/rust/compile/macros/proc/crate_type.rs diff --git a/gcc/testsuite/rust/compile/proc_macro_derive_crate_type.rs b/gcc/testsuite/rust/compile/macros/proc/derive_crate_type.rs index 7d4234b..7d4234b 100644 --- a/gcc/testsuite/rust/compile/proc_macro_derive_crate_type.rs +++ b/gcc/testsuite/rust/compile/macros/proc/derive_crate_type.rs diff --git a/gcc/testsuite/rust/compile/proc_macro_derive_malformed.rs b/gcc/testsuite/rust/compile/macros/proc/derive_malformed.rs index d83256b..d83256b 100644 --- a/gcc/testsuite/rust/compile/proc_macro_derive_malformed.rs +++ b/gcc/testsuite/rust/compile/macros/proc/derive_malformed.rs diff --git a/gcc/testsuite/rust/compile/proc_macro_derive_non_function.rs b/gcc/testsuite/rust/compile/macros/proc/derive_non_function.rs index 7cb4c0b..7cb4c0b 100644 --- a/gcc/testsuite/rust/compile/proc_macro_derive_non_function.rs +++ b/gcc/testsuite/rust/compile/macros/proc/derive_non_function.rs diff --git a/gcc/testsuite/rust/compile/proc_macro_derive_non_root_function.rs b/gcc/testsuite/rust/compile/macros/proc/derive_non_root_function.rs index 69d5ca1..69d5ca1 100644 --- a/gcc/testsuite/rust/compile/proc_macro_derive_non_root_function.rs +++ b/gcc/testsuite/rust/compile/macros/proc/derive_non_root_function.rs diff --git a/gcc/testsuite/rust/compile/proc_macro_derive_non_root_module.rs b/gcc/testsuite/rust/compile/macros/proc/derive_non_root_module.rs index 45d7a47..45d7a47 100644 --- a/gcc/testsuite/rust/compile/proc_macro_derive_non_root_module.rs +++ b/gcc/testsuite/rust/compile/macros/proc/derive_non_root_module.rs diff --git a/gcc/testsuite/rust/compile/proc_macro_derive_private.rs b/gcc/testsuite/rust/compile/macros/proc/derive_private.rs index 69922be..69922be 100644 --- a/gcc/testsuite/rust/compile/proc_macro_derive_private.rs +++ b/gcc/testsuite/rust/compile/macros/proc/derive_private.rs diff --git a/gcc/testsuite/rust/compile/proc_macro_non_function.rs b/gcc/testsuite/rust/compile/macros/proc/non_function.rs index ff2083c..ff2083c 100644 --- a/gcc/testsuite/rust/compile/proc_macro_non_function.rs +++ b/gcc/testsuite/rust/compile/macros/proc/non_function.rs diff --git a/gcc/testsuite/rust/compile/proc_macro_non_root_function.rs b/gcc/testsuite/rust/compile/macros/proc/non_root_function.rs index 9309940..9309940 100644 --- a/gcc/testsuite/rust/compile/proc_macro_non_root_function.rs +++ b/gcc/testsuite/rust/compile/macros/proc/non_root_function.rs diff --git a/gcc/testsuite/rust/compile/proc_macro_non_root_method.rs b/gcc/testsuite/rust/compile/macros/proc/non_root_method.rs index ee52c324..ee52c324 100644 --- a/gcc/testsuite/rust/compile/proc_macro_non_root_method.rs +++ b/gcc/testsuite/rust/compile/macros/proc/non_root_method.rs diff --git a/gcc/testsuite/rust/compile/proc_macro_non_root_module.rs b/gcc/testsuite/rust/compile/macros/proc/non_root_module.rs index 1028612..1028612 100644 --- a/gcc/testsuite/rust/compile/proc_macro_non_root_module.rs +++ b/gcc/testsuite/rust/compile/macros/proc/non_root_module.rs diff --git a/gcc/testsuite/rust/compile/proc_macro_derive_non_root_method.rs b/gcc/testsuite/rust/compile/macros/proc/non_root_trait_method.rs index 523b37a..523b37a 100644 --- a/gcc/testsuite/rust/compile/proc_macro_derive_non_root_method.rs +++ b/gcc/testsuite/rust/compile/macros/proc/non_root_trait_method.rs diff --git a/gcc/testsuite/rust/compile/proc_macro_private.rs b/gcc/testsuite/rust/compile/macros/proc/private.rs index 17e85f4..17e85f4 100644 --- a/gcc/testsuite/rust/compile/proc_macro_private.rs +++ b/gcc/testsuite/rust/compile/macros/proc/private.rs diff --git a/gcc/testsuite/rust/compile/macros/proc/proc_macro.exp b/gcc/testsuite/rust/compile/macros/proc/proc_macro.exp new file mode 100644 index 0000000..ac891db --- /dev/null +++ b/gcc/testsuite/rust/compile/macros/proc/proc_macro.exp @@ -0,0 +1,35 @@ +# 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/>. + +# Compile tests, no torture testing. +# +# These tests raise errors in the front end; torture testing doesn't apply. + +# 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 "compile" +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/compile/proc_macro_pub_function.rs b/gcc/testsuite/rust/compile/macros/proc/pub_function.rs index 52f5d38..52f5d38 100644 --- a/gcc/testsuite/rust/compile/proc_macro_pub_function.rs +++ b/gcc/testsuite/rust/compile/macros/proc/pub_function.rs diff --git a/gcc/testsuite/rust/compile/proc_macro_pub_module.rs b/gcc/testsuite/rust/compile/macros/proc/pub_module.rs index a8bc0e8..a8bc0e8 100644 --- a/gcc/testsuite/rust/compile/proc_macro_pub_module.rs +++ b/gcc/testsuite/rust/compile/macros/proc/pub_module.rs diff --git a/gcc/testsuite/rust/compile/match8.rs b/gcc/testsuite/rust/compile/match8.rs new file mode 100644 index 0000000..336b313 --- /dev/null +++ b/gcc/testsuite/rust/compile/match8.rs @@ -0,0 +1,19 @@ +union MyUnion { + f1: u32, + f2: f32, +} + +fn f(u: MyUnion) -> i32 { + unsafe { + match u { + MyUnion { f1: 10 } => 0, + MyUnion { f2 } => 0, + MyUnion { f1: 10, f2: 10.0 } => 0, // { dg-error "union patterns should have exactly one field" "" } + MyUnion {} => 0, // { dg-error "union patterns should have exactly one field" "" } + MyUnion { f1: () } => 0, // { dg-error "expected u32, found tuple" "" } + _ => 1, + } + } +} + +fn main() {} diff --git a/gcc/testsuite/rust/compile/match9.rs b/gcc/testsuite/rust/compile/match9.rs new file mode 100644 index 0000000..115d458 --- /dev/null +++ b/gcc/testsuite/rust/compile/match9.rs @@ -0,0 +1,30 @@ +enum E { + A(), + B, +} + +const CONST_E: E = E::A(); + +static static_e: E = E::A(); + +type type_alias = E; + +fn f(e: E) { + match e { + E::A => {} + // { dg-error "expected unit struct, unit variant or constant, found tuple variant .E::A." "" { target *-*-* } .-1 } + E::B => {} + crate::CONST_E => {} + crate::type_alias => {} + // { dg-error "expected unit struct, unit variant or constant, found type alias .crate::type_alias." "" { target *-*-* } .-1 } + crate::E => {} + // { dg-error "expected unit struct, unit variant or constant, found enum .crate::E." "" { target *-*-* } .-1 } + crate::static_e => {} + // { dg-error "expected unit struct, unit variant or constant, found static .crate::static_e." "" { target *-*-* } .-1 } + crate::f => {} + // { dg-error "expected unit struct, unit variant or constant, found function .crate::f." "" { target *-*-* } .-1 } + _ => {} + } +} + +fn main() {} diff --git a/gcc/testsuite/rust/compile/method2.rs b/gcc/testsuite/rust/compile/method2.rs index c8699f7..961a039 100644 --- a/gcc/testsuite/rust/compile/method2.rs +++ b/gcc/testsuite/rust/compile/method2.rs @@ -12,5 +12,5 @@ fn main() { let b; b = a.test::<asfasfr>(false); - // { dg-error "failed to resolve TypePath: asfasfr" "" { target *-*-* } .-1 } + // { dg-error "could not resolve type path .asfasfr." "" { target *-*-* } .-1 } } diff --git a/gcc/testsuite/rust/compile/min_specialization1.rs b/gcc/testsuite/rust/compile/min_specialization1.rs new file mode 100644 index 0000000..d38167e --- /dev/null +++ b/gcc/testsuite/rust/compile/min_specialization1.rs @@ -0,0 +1,15 @@ +#![feature(min_specialization)] + +pub trait Foo { + fn foo(&self) -> bool { + false + } +} + +pub struct Bar; + +impl Foo for Bar { + default fn foo(&self) -> bool { // { dg-warning "unused" } + true + } +} diff --git a/gcc/testsuite/rust/compile/multiline-string.rs b/gcc/testsuite/rust/compile/multiline-string.rs new file mode 100644 index 0000000..fcd6fa8 --- /dev/null +++ b/gcc/testsuite/rust/compile/multiline-string.rs @@ -0,0 +1,14 @@ +fn main() { + let _a = "gcc + + rs"; + + let _b = "rust + + c + gcc + + + + rs"; +} diff --git a/gcc/testsuite/rust/compile/multiple_bindings1.rs b/gcc/testsuite/rust/compile/multiple_bindings1.rs index e73dc2a..8a2e18c 100644 --- a/gcc/testsuite/rust/compile/multiple_bindings1.rs +++ b/gcc/testsuite/rust/compile/multiple_bindings1.rs @@ -1,29 +1,38 @@ +#[lang = "sized"] +pub trait Sized {} + +#[lang = "fn_once"] +trait FnOnce<Args> { + type Output; + + fn call_once(self, args: Args) -> Self::Output; +} + fn f1(i: i32, i: i32) {} // { dg-error "identifier .i. is bound more than once in the same parameter list .E0415." "" { target *-*-* } .-1 } trait Foo { - fn f2(i: i32, i: i32) {} - // { dg-error "identifier .i. is bound more than once in the same parameter list .E0415." "" { target *-*-* } .-1 } + fn f2(i: i32, i: i32) {} + // { dg-error "identifier .i. is bound more than once in the same parameter list .E0415." "" { target *-*-* } .-1 } } trait Bar { - fn f3(i: i32, j: i32) {} + fn f3(i: i32, j: i32) {} } struct S; impl S { - fn f4(i: i32, i: i32) {} - // { dg-error "identifier .i. is bound more than once in the same parameter list .E0415." "" { target *-*-* } .-1 } + fn f4(i: i32, i: i32) {} + // { dg-error "identifier .i. is bound more than once in the same parameter list .E0415." "" { target *-*-* } .-1 } } impl Bar for S { - fn f3(i: i32, i: i32) {} - // { dg-error "identifier .i. is bound more than once in the same parameter list .E0415." "" { target *-*-* } .-1 } + fn f3(i: i32, i: i32) {} + // { dg-error "identifier .i. is bound more than once in the same parameter list .E0415." "" { target *-*-* } .-1 } } fn main() { - let _ = |i, i| {}; - // { dg-error "identifier .i. is bound more than once in the same parameter list .E0415." "" { target *-*-* } .-1 } + let _ = |i, i| {}; + // { dg-error "identifier .i. is bound more than once in the same parameter list .E0415." "" { target *-*-* } .-1 } } - diff --git a/gcc/testsuite/rust/compile/mutability_checks1.rs b/gcc/testsuite/rust/compile/mutability_checks1.rs new file mode 100644 index 0000000..4affae0 --- /dev/null +++ b/gcc/testsuite/rust/compile/mutability_checks1.rs @@ -0,0 +1,15 @@ +pub fn test() { + let a; + a = 1; + a = 2 + 1; + // { dg-error "assignment of read-only variable" "" { target *-*-* } .-1 } + + struct Foo(i32); + let a = Foo(1); + a.0 = 2; + // { dg-error "assignment of read-only variable" "" { target *-*-* } .-1 } + + let a = [1, 2, 3, 4]; + a[0] = 1 + 2; + // { dg-error "assignment of read-only variable" "" { target *-*-* } .-1 } +} diff --git a/gcc/testsuite/rust/compile/name_resolution9.rs b/gcc/testsuite/rust/compile/name_resolution9.rs index 93adb46..792b3bd 100644 --- a/gcc/testsuite/rust/compile/name_resolution9.rs +++ b/gcc/testsuite/rust/compile/name_resolution9.rs @@ -6,11 +6,11 @@ pub mod foo { super::super::super::foo!(); // { dg-error "too many leading .super. keywords" } // { dg-error "could not resolve macro invocation" "" { target *-*-* } .-1 } - super::crate::foo!(); // { dg-error "leading path segment .crate. can only be used" } + super::crate::foo!(); // { dg-error ".crate. in paths can only be used" } // { dg-error "could not resolve macro invocation" "" { target *-*-* } .-1 } - crate::foo::bar::super::foo!(); // { dg-error "leading path segment .super. can only be used" } + crate::foo::bar::super::foo!(); // { dg-error ".super. in paths can only be used" } // { dg-error "could not resolve macro invocation" "" { target *-*-* } .-1 } } } diff --git a/gcc/testsuite/rust/compile/nested_macro_use2.rs b/gcc/testsuite/rust/compile/nested_macro_use2.rs index 4659500..7bb6154 100644 --- a/gcc/testsuite/rust/compile/nested_macro_use2.rs +++ b/gcc/testsuite/rust/compile/nested_macro_use2.rs @@ -8,5 +8,5 @@ mod foo { } fn main() { - baz!(); // { dg-error "unknown macro: .baz." } + baz!(); // { dg-error "could not resolve macro invocation .baz." } } diff --git a/gcc/testsuite/rust/compile/nonexistent-field.rs b/gcc/testsuite/rust/compile/nonexistent-field.rs new file mode 100644 index 0000000..9bcfb2f --- /dev/null +++ b/gcc/testsuite/rust/compile/nonexistent-field.rs @@ -0,0 +1,14 @@ +#![allow(unused)] +fn main() { + struct StructWithFields { + x: u32, + } + + let s = StructWithFields { x: 0 }; + s.foo; + // { dg-error "no field .foo. on type .StructWithFields. .E0609." "" { target *-*-* } .-1 } + + let numbers = (1, 2, 3); + numbers.3; + // { dg-error "no field .3. on type ..<integer>, <integer>, <integer>.. .E0609." "" { target *-*-* } .-1 } +} diff --git a/gcc/testsuite/rust/compile/nr2/compile.exp b/gcc/testsuite/rust/compile/nr2/compile.exp new file mode 100644 index 0000000..9e15cdd --- /dev/null +++ b/gcc/testsuite/rust/compile/nr2/compile.exp @@ -0,0 +1,149 @@ +# 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 new file mode 100644 index 0000000..c020e36 --- /dev/null +++ b/gcc/testsuite/rust/compile/nr2/exclude @@ -0,0 +1,17 @@ +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/prelude_import.rs b/gcc/testsuite/rust/compile/prelude_import.rs new file mode 100644 index 0000000..569fb62 --- /dev/null +++ b/gcc/testsuite/rust/compile/prelude_import.rs @@ -0,0 +1,12 @@ +#![feature(prelude_import)] + +mod core { + mod prelude { + mod v1 { + // hehe + } + } +} + +#[prelude_import] +use core::prelude::v1::*; diff --git a/gcc/testsuite/rust/compile/ptr_int_cast.rs b/gcc/testsuite/rust/compile/ptr_int_cast.rs new file mode 100644 index 0000000..3a2a5d5 --- /dev/null +++ b/gcc/testsuite/rust/compile/ptr_int_cast.rs @@ -0,0 +1,18 @@ +fn main(){ + let foo = 1337; + let bar_ptr = &foo as *const i32; + + let bar_ptr_usize = bar_ptr as usize; + let bar_ptr_isize = bar_ptr as isize; + let bar_ptr_u64 = bar_ptr as u64; + let bar_ptr_i64 = bar_ptr as i64; + let bar_ptr_i8 = bar_ptr as i8; + let bar_ptr_u8 = bar_ptr as u8; + + let _ = bar_ptr_usize as *const i32; + let _ = bar_ptr_isize as *const i32; + let _ = bar_ptr_u64 as *const i32; + let _ = bar_ptr_i64 as *const i32; + let _ = bar_ptr_i8 as *const i32; + let _ = bar_ptr_u8 as *const i32; +} diff --git a/gcc/testsuite/rust/compile/redef_error2.rs b/gcc/testsuite/rust/compile/redef_error2.rs index 65793bc..ed946f8 100644 --- a/gcc/testsuite/rust/compile/redef_error2.rs +++ b/gcc/testsuite/rust/compile/redef_error2.rs @@ -1,4 +1,4 @@ const TEST: i32 = 2; -const TEST: f32 = 3.0; // { dg-error "redefined multiple times" } +const TEST: f32 = 3.0; // { dg-error "defined multiple times" } fn main() {} diff --git a/gcc/testsuite/rust/compile/redef_error5.rs b/gcc/testsuite/rust/compile/redef_error5.rs index dc6ad50..b3d71e1 100644 --- a/gcc/testsuite/rust/compile/redef_error5.rs +++ b/gcc/testsuite/rust/compile/redef_error5.rs @@ -2,7 +2,7 @@ struct Foo(i32, bool); impl Foo { const TEST: i32 = 123; - const TEST: bool = false; // { dg-error "redefined multiple times" } + const TEST: bool = false; // { dg-error "defined multiple times" } } fn main() {} diff --git a/gcc/testsuite/rust/compile/reference1.rs b/gcc/testsuite/rust/compile/reference1.rs index 2f94754..28f7a26 100644 --- a/gcc/testsuite/rust/compile/reference1.rs +++ b/gcc/testsuite/rust/compile/reference1.rs @@ -2,5 +2,5 @@ fn main() { let a = &123; let b: &mut i32 = a; // { dg-error "mismatched mutability" "" { target *-*-* } .-1 } - // { dg-error "mismatched types, expected .&mut i32. but got .& i32." "" { target *-*-* } .-2 } + // { dg-error "mismatched types, expected .&mut i32. but got .& <integer>." "" { target *-*-* } .-2 } } diff --git a/gcc/testsuite/rust/compile/self-path2.rs b/gcc/testsuite/rust/compile/self-path2.rs index b9b82ca..d955ed0 100644 --- a/gcc/testsuite/rust/compile/self-path2.rs +++ b/gcc/testsuite/rust/compile/self-path2.rs @@ -11,11 +11,11 @@ fn baz() { crate::bar(); crate::self::foo(); - // { dg-error "failed to resolve: .self. in paths can only be used in start position" "" { target *-*-* } .-1 } + // { dg-error ".self. in paths can only be used in start position" "" { target *-*-* } .-1 } } type a = foo; type b = crate::foo; type c = self::foo; type d = crate::self::foo; -// { dg-error "failed to resolve: .self. in paths can only be used in start position" "" { target *-*-* } .-1 } +// { dg-error ".self. in paths can only be used in start position" "" { target *-*-* } .-1 } diff --git a/gcc/testsuite/rust/compile/self_import_namespace.rs b/gcc/testsuite/rust/compile/self_import_namespace.rs new file mode 100644 index 0000000..2d9b2ed --- /dev/null +++ b/gcc/testsuite/rust/compile/self_import_namespace.rs @@ -0,0 +1,14 @@ +// { dg-additional-options "-frust-name-resolution-2.0" } + +mod bar { + pub mod foo {} + pub fn foo() {} +} + +// This only imports the module `foo`. The function `foo` lives in +// the value namespace and is not imported. +use bar::foo::{self}; + +fn main() { + foo(); // { dg-error "expected value" } +} diff --git a/gcc/testsuite/rust/compile/sizeof-stray-infer-var-bug.rs b/gcc/testsuite/rust/compile/sizeof-stray-infer-var-bug.rs index a5f0c2b..c46a97d 100644 --- a/gcc/testsuite/rust/compile/sizeof-stray-infer-var-bug.rs +++ b/gcc/testsuite/rust/compile/sizeof-stray-infer-var-bug.rs @@ -1,3 +1,5 @@ +#![feature(intrinsics)] + #[lang = "sized"] pub trait Sized {} @@ -12,6 +14,6 @@ mod ptr { pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) { let x = x as *mut T; let y = y as *mut T; - let len = mem::size_of::<T>() * count; + let len = crate::mem::size_of::<T>() * count; } } diff --git a/gcc/testsuite/rust/compile/struct_init1.rs b/gcc/testsuite/rust/compile/struct_init1.rs index 1875fb4..38f6f38 100644 --- a/gcc/testsuite/rust/compile/struct_init1.rs +++ b/gcc/testsuite/rust/compile/struct_init1.rs @@ -4,7 +4,7 @@ struct Foo { } fn main() { - let a = Foo { 0: 10.0, 1: 20.0 }; // { dg-error "failed to resolve type for field" } - // { dg-error "unknown field" "" { target *-*-* } .-1 } - // { dg-prune-output "compilation terminated" } + let a = Foo { 0: 10.0, 1: 20.0 }; + // { dg-error "unknown field .0. .E0560." "" { target *-*-* } .-1 } + // { dg-error "unknown field .1. .E0560." "" { target *-*-* } .-2 } } diff --git a/gcc/testsuite/rust/compile/structural-eq-peq.rs b/gcc/testsuite/rust/compile/structural-eq-peq.rs new file mode 100644 index 0000000..d04c295 --- /dev/null +++ b/gcc/testsuite/rust/compile/structural-eq-peq.rs @@ -0,0 +1,9 @@ +#[lang = "structural_peq"] +pub trait StructuralPartialEq { + // Empty. +} + +#[lang = "structural_teq"] +pub trait StructuralEq { + // Empty. +} diff --git a/gcc/testsuite/rust/compile/torture/builtin_abort.rs b/gcc/testsuite/rust/compile/torture/builtin_abort.rs index 3112cdc..919caa4 100644 --- a/gcc/testsuite/rust/compile/torture/builtin_abort.rs +++ b/gcc/testsuite/rust/compile/torture/builtin_abort.rs @@ -12,7 +12,7 @@ mod intrinsics { } } -pub fn main () -> i32 { - abort(); +pub fn main() -> i32 { + crate::intrinsics::abort(); 0 } diff --git a/gcc/testsuite/rust/compile/torture/if.rs b/gcc/testsuite/rust/compile/torture/if.rs index bcd520f..3b753a7 100644 --- a/gcc/testsuite/rust/compile/torture/if.rs +++ b/gcc/testsuite/rust/compile/torture/if.rs @@ -4,6 +4,10 @@ fn foo() -> bool { fn bar() {} +fn baz(a: i32) { + a; +} + struct Foo1 { one: i32 } @@ -13,7 +17,7 @@ fn main() { if foo() { bar(); let a = Foo1{one: 1}; - a.one + baz (a.one); } -}
\ No newline at end of file +} diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-8.rs b/gcc/testsuite/rust/compile/torture/intrinsics-8.rs index deb19bd..b9bd83c 100644 --- a/gcc/testsuite/rust/compile/torture/intrinsics-8.rs +++ b/gcc/testsuite/rust/compile/torture/intrinsics-8.rs @@ -1,3 +1,5 @@ +#![feature(intrinsics)] + #[lang = "sized"] pub trait Sized {} diff --git a/gcc/testsuite/rust/compile/torture/transmute-size-check-1.rs b/gcc/testsuite/rust/compile/torture/transmute-size-check-1.rs index 6d34fb1..7b98779 100644 --- a/gcc/testsuite/rust/compile/torture/transmute-size-check-1.rs +++ b/gcc/testsuite/rust/compile/torture/transmute-size-check-1.rs @@ -1,3 +1,5 @@ +#![feature(intrinsics)] + #[lang = "sized"] pub trait Sized {} diff --git a/gcc/testsuite/rust/compile/torture/transmute1.rs b/gcc/testsuite/rust/compile/torture/transmute1.rs index b2a0d07..be9fb1d 100644 --- a/gcc/testsuite/rust/compile/torture/transmute1.rs +++ b/gcc/testsuite/rust/compile/torture/transmute1.rs @@ -1,3 +1,5 @@ +#![feature(intrinsics)] + #[lang = "sized"] pub trait Sized {} diff --git a/gcc/testsuite/rust/compile/torture/uninit-intrinsic-1.rs b/gcc/testsuite/rust/compile/torture/uninit-intrinsic-1.rs index cbb92fe..af1cb54 100644 --- a/gcc/testsuite/rust/compile/torture/uninit-intrinsic-1.rs +++ b/gcc/testsuite/rust/compile/torture/uninit-intrinsic-1.rs @@ -1,3 +1,5 @@ +#![feature(intrinsics)] + #[lang = "sized"] pub trait Sized {} @@ -9,7 +11,7 @@ mod intrinsics { mod mem { pub unsafe fn uninitialized<T>() -> T { - intrinsics::uninit() + crate::intrinsics::uninit() } } @@ -19,6 +21,6 @@ struct Foo(i32, i32); impl Foo { pub fn new() -> Self { - unsafe { mem::uninitialized::<Foo>() } + unsafe { crate::mem::uninitialized::<Foo>() } } } diff --git a/gcc/testsuite/rust/compile/track_caller.rs b/gcc/testsuite/rust/compile/track_caller.rs new file mode 100644 index 0000000..fd1d842 --- /dev/null +++ b/gcc/testsuite/rust/compile/track_caller.rs @@ -0,0 +1,6 @@ +#[track_caller] +fn foo() {} + +fn main() { + foo(); +} diff --git a/gcc/testsuite/rust/compile/trait13.rs b/gcc/testsuite/rust/compile/trait13.rs new file mode 100644 index 0000000..af5f5a6 --- /dev/null +++ b/gcc/testsuite/rust/compile/trait13.rs @@ -0,0 +1,47 @@ +// Testing multiple supertraits and calling supertrait methods + +struct Foo { + my_int: u32, +} + +trait GrandParent { + fn grandparent(&self) -> u32; +} + +trait Parent : GrandParent { + fn parent(&self) -> bool; +} + +trait Child : Parent { + fn child(&self); +} + +impl GrandParent for Foo { + fn grandparent(&self) -> u32 { + self.my_int + } +} + +impl Parent for Foo { + fn parent(&self) -> bool { + // Call supertrait method + return self.grandparent() != 0; + } +} + +impl Child for Foo { + fn child(&self) { + let _ = self; + } +} + +pub fn main() { + let a = Foo{my_int: 0xfeedf00d}; + let b: &dyn Child = &a; + + b.parent(); + b.child(); + + // Here to silence bogus compiler warning + let _ = a.my_int; +} diff --git a/gcc/testsuite/rust/compile/trait14.rs b/gcc/testsuite/rust/compile/trait14.rs new file mode 100644 index 0000000..c1d42b5 --- /dev/null +++ b/gcc/testsuite/rust/compile/trait14.rs @@ -0,0 +1,51 @@ +// Testing diamond problem with supertraits + + +struct Foo { + my_int: u32, +} + +trait GrandParent { + fn grandparent(&self); +} + +trait Parent1 : GrandParent { + fn parent1(&self); +} + +trait Parent2 : GrandParent { + fn parent2(&self); +} + +trait Child : Parent1+Parent2 { + fn child(&self); +} + +impl GrandParent for Foo { + fn grandparent(&self) { let _ = self; } +} + +impl Parent1 for Foo { + fn parent1(&self) { let _ = self; } +} + +impl Parent2 for Foo { + fn parent2(&self) { let _ = self; } +} + +impl Child for Foo { + fn child(&self) { + let _ = self; + } +} + +pub fn main() { + let a = Foo{my_int: 0xf00dfeed}; + let b: &dyn Child = &a; + + b.parent1(); + b.child(); + + // Suppress bogus compile warning + let _ = a.my_int; +} diff --git a/gcc/testsuite/rust/compile/try-catch-unwind-new.rs b/gcc/testsuite/rust/compile/try-catch-unwind-new.rs new file mode 100644 index 0000000..b176f7a --- /dev/null +++ b/gcc/testsuite/rust/compile/try-catch-unwind-new.rs @@ -0,0 +1,20 @@ +// { dg-options "-O2 -w -fdump-tree-optimized" } +#![feature(intrinsics)] + +extern "rust-intrinsic" { + // { dg-final { scan-tree-dump-times "__builtin_eh_pointer" 1 "optimized" } } + fn catch_unwind(try_fn: fn(_: *mut u8), data: *mut u8, catch_fn: fn(_: *mut u8, _: *mut u8)); +} + +extern "C" { + fn try_fn(data: *mut u8); + fn catch_fn(data: *mut u8, ex: *mut u8); +} + +pub fn not_main(d: &mut u8) { + unsafe { + // { dg-final { scan-tree-dump-times "try_fn" 1 "optimized" } } + catch_unwind(try_fn, d, catch_fn); + // { dg-final { scan-tree-dump-times "catch_fn" 1 "optimized" } } + } +} diff --git a/gcc/testsuite/rust/compile/try-catch-unwind-old.rs b/gcc/testsuite/rust/compile/try-catch-unwind-old.rs new file mode 100644 index 0000000..e97d52c --- /dev/null +++ b/gcc/testsuite/rust/compile/try-catch-unwind-old.rs @@ -0,0 +1,21 @@ +// { dg-options "-O2 -w -fdump-tree-optimized" } +#![feature(intrinsics)] + +extern "rust-intrinsic" { + // { dg-final { scan-tree-dump-times "__builtin_eh_pointer" 1 "optimized" } } + fn r#try(try_fn: fn(_: *mut u8), data: *mut u8, catch_fn: fn(_: *mut u8, _: *mut u8)) -> i32; +} + +extern "C" { + fn try_fn(data: *mut u8); + fn catch_fn(data: *mut u8, ex: *mut u8); +} + +pub fn not_main(d: &mut u8) -> i32 { + unsafe { + // { dg-final { scan-tree-dump-times "try_fn" 1 "optimized" } } + let _: i32 = r#try(try_fn, d, catch_fn); + // { dg-final { scan-tree-dump-times "catch_fn" 1 "optimized" } } + } + 42 +} diff --git a/gcc/testsuite/rust/compile/try-expr1.rs b/gcc/testsuite/rust/compile/try-expr1.rs new file mode 100644 index 0000000..f1a7865 --- /dev/null +++ b/gcc/testsuite/rust/compile/try-expr1.rs @@ -0,0 +1,84 @@ +// { dg-additional-options "-frust-compile-until=typecheck" } + +#[lang = "sized"] +trait Sized {} + +enum Result { + #[lang = "Ok"] + Ok(i32), + #[lang = "Err"] + Err(i32) +} + +pub trait From<T>: Sized { + /// Performs the conversion. + #[lang = "from"] + #[stable(feature = "rust1", since = "1.0.0")] + fn from(_: T) -> Self; +} + +impl<T> From<T> for T { + fn from(t: T) -> Self { t } +} + +#[lang = "try"] +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; + + /// 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: i32) -> 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: i32) -> Self; +} + +impl Try for Result { + // type Ok = i32; + // type Error = i32; + + fn into_result(self) -> Result { + self + } + + fn from_ok(v: i32) -> Self { + Result::Ok(v) + } + + fn from_error(v: i32) -> Self { + Result::Err(v) + } +} + +fn bar() -> Result { + Result::Ok(15) +} + +fn foo() -> Result { + let a = bar()?; + + Result::Ok(a) +} diff --git a/gcc/testsuite/rust/compile/try-trait.rs b/gcc/testsuite/rust/compile/try-trait.rs new file mode 100644 index 0000000..9ec135d --- /dev/null +++ b/gcc/testsuite/rust/compile/try-trait.rs @@ -0,0 +1,44 @@ +#[lang = "sized"] +trait Sized {} + +enum Result<T, E> { + #[lang = "Ok"] + Ok(T), + #[lang = "Err"] + Err(E) +} + +#[lang = "try"] +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; +} diff --git a/gcc/testsuite/rust/compile/type-bindings1.rs b/gcc/testsuite/rust/compile/type-bindings1.rs index 358035b..ef0b471 100644 --- a/gcc/testsuite/rust/compile/type-bindings1.rs +++ b/gcc/testsuite/rust/compile/type-bindings1.rs @@ -7,5 +7,4 @@ fn main() { let a; a = Foo::<A = i32, B = f32>(123f32); // { dg-error "associated type bindings are not allowed here" "" { target *-*-* } .-1 } - // { dg-error {Failed to resolve expression of function call} "" { target *-*-* } .-2 } } diff --git a/gcc/testsuite/rust/compile/unconstrained_type_param.rs b/gcc/testsuite/rust/compile/unconstrained_type_param.rs index 1cef0b9..60554da 100644 --- a/gcc/testsuite/rust/compile/unconstrained_type_param.rs +++ b/gcc/testsuite/rust/compile/unconstrained_type_param.rs @@ -13,5 +13,4 @@ impl<X, Y> Foo<X> { fn main() { let a = Foo::test(); // { dg-error "expected" "" { target *-*-* } .-1 } - // { dg-error "Failed to resolve expression of function call" "" { target *-*-* } .-2 } } diff --git a/gcc/testsuite/rust/compile/undeclared_label.rs b/gcc/testsuite/rust/compile/undeclared_label.rs index 6efa2d9..9aa0553 100644 --- a/gcc/testsuite/rust/compile/undeclared_label.rs +++ b/gcc/testsuite/rust/compile/undeclared_label.rs @@ -2,12 +2,12 @@ #![allow(unused)] fn resolve_label_continue() -> () { loop { - continue 'a; // { dg-error "use of undeclared label .a. in .continue." } + continue 'a; // { dg-error "use of undeclared label .'a." } } } fn resolve_label_break() -> () { loop { - break 'crabby; // { dg-error "use of undeclared label .crabby. in .break." } + break 'crabby; // { dg-error "use of undeclared label .'crabby." } } } fn main() { diff --git a/gcc/testsuite/rust/compile/use_1.rs b/gcc/testsuite/rust/compile/use_1.rs index 94b9632..e8e2037 100644 --- a/gcc/testsuite/rust/compile/use_1.rs +++ b/gcc/testsuite/rust/compile/use_1.rs @@ -1,7 +1,8 @@ +// { dg-additional-options "-frust-name-resolution-2.0" } mod frob {} -use foo::bar::baz; // { dg-error "cannot find simple path segment .foo." } -use frob::ulator; // { dg-error "cannot find simple path segment .ulator." } +use foo::bar::baz; // { dg-error "unresolved import .foo::bar::baz." } +use frob::ulator; // { dg-error "unresolved import .frob::ulator." } mod sain { mod doux {} @@ -9,8 +10,8 @@ mod sain { mod dron {} } -use not_sain::*; // { dg-error "cannot find simple path segment .not_sain." } +use not_sain::*; // { dg-error "unresolved import .not_sain." } use sain::*; use sain::{doux, dron}; -use sain::{doux, dron, graal}; // { dg-error "cannot find simple path segment .graal." } +use sain::{doux, dron, graal}; // { dg-error "unresolved import .sain::graal." } diff --git a/gcc/testsuite/rust/compile/v0-mangle1.rs b/gcc/testsuite/rust/compile/v0-mangle1.rs index a34f1a7..04c546e 100644 --- a/gcc/testsuite/rust/compile/v0-mangle1.rs +++ b/gcc/testsuite/rust/compile/v0-mangle1.rs @@ -36,7 +36,7 @@ fn main() { // cf. rustc 1.72.0: _RNvNtCshIBIgX6Bzox_10v0_mangle18module_a3bar module_a::bar(); - // { dg-final { scan-assembler "_R.*NvNtNtC10v0_mangle18module_a8module_b3baz" } } + // { dg-final { scan-assembler "_R.*NvNtNtC.*10v0_mangle18module_a8module_b3baz" } } // cf. rustc 1.72.0: _RNvNtNtCshIBIgX6Bzox_10v0_mangle18module_a8module_b3baz module_a::module_b::baz(); diff --git a/gcc/testsuite/rust/compile/name_resolution21.rs b/gcc/testsuite/rust/compile/xfail/name_resolution21.rs index 3d0af2b..df48d00 100644 --- a/gcc/testsuite/rust/compile/name_resolution21.rs +++ b/gcc/testsuite/rust/compile/xfail/name_resolution21.rs @@ -5,7 +5,8 @@ pub mod foo { } use foo::bar; -use foo::bar; // { dg-error ".bar. defined multiple times" } +use foo::bar; +// { dg-error ".bar. defined multiple times" "" { xfail *-*-* } .-1 } fn main() { bar!(); |