diff --git a/gcc/testsuite/rust/compile/abi-options1.rs b/gcc/testsuite/rust/compile/abi-options1.rs
new file mode 100644
index 00000000000..a4b6241dc15
--- /dev/null
+++ b/gcc/testsuite/rust/compile/abi-options1.rs
@@ -0,0 +1,7 @@
+extern "foobar" {
+    // { dg-error "unknown ABI option" "" { target *-*-* } .-1 }
+    fn printf(s: *const i8, ...);
+}
+
+pub extern "baz" fn test() {}
+// { dg-error "unknown ABI option" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/array3.rs b/gcc/testsuite/rust/compile/array3.rs
new file mode 100644
index 00000000000..a56be9a0e8b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/array3.rs
@@ -0,0 +1,4 @@
+fn foo(state: &mut [u32; 16], a: usize) {
+    // { dg-warning "function is never used: .foo." "" { target *-*-* } .-1 }
+    state[a] = 1;
+}
diff --git a/gcc/testsuite/rust/compile/array_empty_list.rs b/gcc/testsuite/rust/compile/array_empty_list.rs
new file mode 100644
index 00000000000..76e082a6d57
--- /dev/null
+++ b/gcc/testsuite/rust/compile/array_empty_list.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let arr = [];
+    // { dg-error "type annotations needed" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/arrays1.rs b/gcc/testsuite/rust/compile/arrays1.rs
new file mode 100644
index 00000000000..714a6be7afb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/arrays1.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let xs: [i32; 5] = [1, 2, 3, 4, 5];
+    let a: bool = xs[0]; // { dg-error "expected .bool. got .i32." }
+}
diff --git a/gcc/testsuite/rust/compile/arrays2.rs b/gcc/testsuite/rust/compile/arrays2.rs
new file mode 100644
index 00000000000..c96f4f7d820
--- /dev/null
+++ b/gcc/testsuite/rust/compile/arrays2.rs
@@ -0,0 +1,5 @@
+// { dg-additional-options "-w" }
+fn main() {
+    let array: [i32; 5] = [1, 2, 3];
+    // { dg-error "expected an array with a fixed size of 5 elements, found one with 3 elements" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/attr-mismatch-crate-name.rs b/gcc/testsuite/rust/compile/attr-mismatch-crate-name.rs
new file mode 100644
index 00000000000..1d406031fee
--- /dev/null
+++ b/gcc/testsuite/rust/compile/attr-mismatch-crate-name.rs
@@ -0,0 +1,4 @@
+// { dg-additional-options "-fdump-tree-gimple" }
+#![crate_name = "specified_name"]
+// { dg-final { scan-tree-dump-times {specified_name::main} 1 gimple } }
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/attr_cold.rs b/gcc/testsuite/rust/compile/attr_cold.rs
new file mode 100644
index 00000000000..f705ea9b2ff
--- /dev/null
+++ b/gcc/testsuite/rust/compile/attr_cold.rs
@@ -0,0 +1,12 @@
+// { dg-additional-options "-fdump-tree-gimple" }
+#[cold]
+fn cold_function() -> i32 {
+    42
+}
+
+fn main() -> i32 {
+    // { dg-final { scan-tree-dump-times {__attribute__\(\(cdecl, cold\)\)} 1 gimple } }
+    cold_function();
+
+    0
+}
diff --git a/gcc/testsuite/rust/compile/attr_deprecated.rs b/gcc/testsuite/rust/compile/attr_deprecated.rs
new file mode 100644
index 00000000000..01bc9c41502
--- /dev/null
+++ b/gcc/testsuite/rust/compile/attr_deprecated.rs
@@ -0,0 +1,14 @@
+#[deprecated(since="1.0", note="do not use this function")]
+fn test1() {}
+
+#[deprecated]
+fn test() {}
+
+#[deprecated = "a different message"]
+fn test2() {}
+
+fn main() {
+    test(); // { dg-warning ".attr_deprecated::test. is deprecated" }
+    test1(); // { dg-warning ".attr_deprecated::test1. is deprecated: do not use this function" }
+    test2(); // { dg-warning ".attr_deprecated::test2. is deprecated: a different message" }
+}
diff --git a/gcc/testsuite/rust/compile/attr_deprecated_2.rs b/gcc/testsuite/rust/compile/attr_deprecated_2.rs
new file mode 100644
index 00000000000..66f4ce3b076
--- /dev/null
+++ b/gcc/testsuite/rust/compile/attr_deprecated_2.rs
@@ -0,0 +1,11 @@
+#[deprecated(since="1.0")]
+fn test1() {}
+
+// { dg-excess-errors "unknown meta item ...." }
+#[deprecated(invalid="invalid")]
+fn test2() {}
+
+fn main() {
+    test1(); // { dg-warning ".attr_deprecated_2::test1. is deprecated" }
+    test2();
+}
diff --git a/gcc/testsuite/rust/compile/bad-crate-name.rs b/gcc/testsuite/rust/compile/bad-crate-name.rs
new file mode 100644
index 00000000000..6c59c255cc2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/bad-crate-name.rs
@@ -0,0 +1,4 @@
+// { dg-additional-options "-frust-crate=bad+name" }
+// { dg-excess-errors "invalid crate name: ...." }
+// { dg-excess-errors "unrecognized command-line option ...." }
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/bad=file-name.rs b/gcc/testsuite/rust/compile/bad=file-name.rs
new file mode 100644
index 00000000000..cfbebb0698d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/bad=file-name.rs
@@ -0,0 +1,7 @@
+// { dg-additional-options "-fdump-tree-gimple -frust-crate=good_name" }
+pub fn does_nothing() {}
+fn main() {
+    does_nothing()
+}
+// { dg-final { scan-tree-dump-times {good_name::does_nothing} 2 gimple } }
+// { dg-final { scan-tree-dump-times {good_name::main} 1 gimple } }
diff --git a/gcc/testsuite/rust/compile/bad_as_bool_char.rs b/gcc/testsuite/rust/compile/bad_as_bool_char.rs
new file mode 100644
index 00000000000..91a28eebe00
--- /dev/null
+++ b/gcc/testsuite/rust/compile/bad_as_bool_char.rs
@@ -0,0 +1,18 @@
+pub fn main ()
+{
+  let t = true;
+  let f = false;
+  let fone = t as f32;   // { dg-error "invalid cast" }
+  let fzero = f as f64;  // { dg-error "invalid cast" }
+
+  let nb = 0u8 as bool;  // { dg-error "invalid cast" }
+  let nc = true as char; // { dg-error "invalid cast" }
+
+  let a = 'a';
+  let b = 'b';
+  let fa = a as f32;     // { dg-error "invalid cast" }
+  let bb = b as bool;    // { dg-error "invalid cast" }
+
+  let t32: u32 = 33;
+  let ab = t32 as char;  // { dg-error "invalid cast" }
+}
diff --git a/gcc/testsuite/rust/compile/bad_file_name.txt.rs b/gcc/testsuite/rust/compile/bad_file_name.txt.rs
new file mode 100644
index 00000000000..56e2093b27c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/bad_file_name.txt.rs
@@ -0,0 +1,3 @@
+// { dg-excess-errors "invalid crate name: ...." }
+// { dg-bogus "unrecognized command-line option ...." }
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/bad_inner_doc.rs b/gcc/testsuite/rust/compile/bad_inner_doc.rs
new file mode 100644
index 00000000000..cfd166ce3ec
--- /dev/null
+++ b/gcc/testsuite/rust/compile/bad_inner_doc.rs
@@ -0,0 +1,15 @@
+pub fn main ()
+{
+  //! inner doc allowed
+  let _x = 42;
+  // { dg-error "inner doc" "" { target *-*-* } .+1 }
+  //! inner doc disallowed
+  mod module
+  {
+    /*! inner doc allowed */
+    /// outer doc allowed
+    // { dg-error "inner doc" "" { target *-*-* } .+1 }
+    /*! but inner doc not here */
+    mod x { }
+  }
+}
diff --git a/gcc/testsuite/rust/compile/bad_pub_enumitems.rs b/gcc/testsuite/rust/compile/bad_pub_enumitems.rs
new file mode 100644
index 00000000000..e7fd5edb981
--- /dev/null
+++ b/gcc/testsuite/rust/compile/bad_pub_enumitems.rs
@@ -0,0 +1,47 @@
+pub enum E
+{
+  pub A { a: i32 }, // { dg-error "visibility qualifier" }
+  B (u8),
+  pub C, // { dg-error "visibility qualifier" }
+  D
+}
+
+enum E1
+{
+  A,
+  pub B = 42, // { dg-error "visibility qualifier" }
+  C = 3,
+  D,
+  pub E // { dg-error "visibility qualifier" }
+}
+
+enum E2
+{
+  pub A (u8, i32, u64), // { dg-error "visibility qualifier" }
+  B { a: u8, a: u8 }  // { dg-error "duplicate field" }}
+}
+
+fn main ()
+{
+  enum EE
+    {
+      Alpha { alpha: i32 },
+      pub Beta (u8), // { dg-error "visibility qualifier" }
+      pub Gamma, // { dg-error "visibility qualifier" }
+      Delta { delta: u32 }
+    }
+
+  enum EE1
+    {
+      pub Alpha, // { dg-error "visibility qualifier" }
+      Beta = 41,
+      pub Gamma = 3, // { dg-error "visibility qualifier" }
+      Delta,
+    }
+
+  enum E2
+    {
+      Alpha { a: u8, a: u8 },  // { dg-error "duplicate field" }}
+      pub Beta (u8, i32, u64) // { dg-error "visibility qualifier" }
+    }
+}
diff --git a/gcc/testsuite/rust/compile/bad_stmt_enums.rs b/gcc/testsuite/rust/compile/bad_stmt_enums.rs
new file mode 100644
index 00000000000..7b09a94fd27
--- /dev/null
+++ b/gcc/testsuite/rust/compile/bad_stmt_enums.rs
@@ -0,0 +1,22 @@
+fn main ()
+{
+  enum EE
+    {
+      Alpha { alpha: i32 },
+      pub Beta (u8),
+      pub Gamma,
+      Gamma { gamma: u32 } // { dg-error "redefined" }
+    }
+
+  struct EE2 { }
+  enum EE2 { } // { dg-error "redefined" }
+
+  enum EE1
+    {
+      pub Alpha,
+      Beta = 41,
+      Beta = 42, // { dg-error "redefined" }
+      pub Gamma = 3,
+      D,
+    }
+}
diff --git a/gcc/testsuite/rust/compile/bad_toplevel_enums.rs b/gcc/testsuite/rust/compile/bad_toplevel_enums.rs
new file mode 100644
index 00000000000..b655e30a93d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/bad_toplevel_enums.rs
@@ -0,0 +1,19 @@
+pub enum E
+{
+  pub A { a: i32 },
+  B (u8),
+  pub C,
+  B // { dg-error "redefined" }
+}
+
+enum E2 { }
+struct E2 { } // { dg-error "redefined" }
+
+enum E1
+{
+  A,
+  pub B = 42,
+  C = 3,
+  A { a: u8 }, // { dg-error "redefined" }
+  pub D
+}
diff --git a/gcc/testsuite/rust/compile/bad_tuple_index.rs b/gcc/testsuite/rust/compile/bad_tuple_index.rs
new file mode 100644
index 00000000000..c3bd1e91d10
--- /dev/null
+++ b/gcc/testsuite/rust/compile/bad_tuple_index.rs
@@ -0,0 +1,66 @@
+fn main()
+{
+  // tuples
+  let z = ();
+
+  let o = (0,);
+  /* Binary, Octal and Hex literals are invalid.  */
+  let _fb = o.0b0; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fo = o.0o0; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fh = o.0x0; // { dg-error "tuple index should be a pure decimal literal" }
+
+  /* No underscores.  */
+  let _fua = o.0_; // { dg-error "tuple index should be a pure decimal literal" }
+
+  /* Suffix is not allowed.  */
+  let _fu8 = o.0u8; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fi8 = o.0i8; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fu16 = o.0u16; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fi16 = o.0i16; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fu32 = o.0u32; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fi32 = o.0i32; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fu64 = o.0u64; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fi64 = o.0i64; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fu128 = o.0u128; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fi128 = o.0i128; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fusize = o.0usize; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fisize = o.0isize; // { dg-error "tuple index should be a pure decimal literal" }
+
+  let t = (0,1);
+  /* No extra zero prefix.  */
+  let _s = t.01; // { dg-error "tuple index should be a pure decimal literal" }
+
+  let m = (0,1,2,3,4,5,6,7,8,9,10);
+  /* No extra zero prefix.  */
+  let _l = m.010; // { dg-error "tuple index should be a pure decimal literal" }
+
+  /* No underscores.  */
+  let _lu = m.1_0; // { dg-error "tuple index should be a pure decimal literal" }
+
+  // tuple structs
+  struct E();
+  let _e = E();
+
+  struct O(i32);
+  let so = O(0);
+  /* No leading zeros, no underscores.  */
+  let _sf = so.0_0; // { dg-error "tuple index should be a pure decimal literal" }
+  /* Binary, Octal and Hex literals are invalid.  */
+  let _sb = so.0b0; // { dg-error "tuple index should be a pure decimal literal" }
+  let _so = so.0o0; // { dg-error "tuple index should be a pure decimal literal" }
+  let _sh = so.0x0; // { dg-error "tuple index should be a pure decimal literal" }
+
+  struct T(i32,i32);
+  let st = T(0,1);
+  /* Suffix is not allowed.  */
+  let _stfu32 = st.1u32; // { dg-error "tuple index should be a pure decimal literal" }
+  let _stfi32 = st.1i32; // { dg-error "tuple index should be a pure decimal literal" }
+
+  struct M(i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,i32);
+  let sm = M(0,1,2,3,4,5,6,7,8,9,10);
+  /* No underscores. */
+  let _sl2 = sm.1_0; // { dg-error "tuple index should be a pure decimal literal" }
+  let _sl3 = sm.10_; // { dg-error "tuple index should be a pure decimal literal" }
+
+  z
+}
diff --git a/gcc/testsuite/rust/compile/bad_type1.rs b/gcc/testsuite/rust/compile/bad_type1.rs
new file mode 100644
index 00000000000..93de439704f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/bad_type1.rs
@@ -0,0 +1,3 @@
+fn main() {
+    let logical: bool = 123; // { dg-error "expected .bool. got .<integer>." }
+}
diff --git a/gcc/testsuite/rust/compile/bad_type2.rs b/gcc/testsuite/rust/compile/bad_type2.rs
new file mode 100644
index 00000000000..e47b8aac0e7
--- /dev/null
+++ b/gcc/testsuite/rust/compile/bad_type2.rs
@@ -0,0 +1,14 @@
+fn test(x: i32) -> i32 {
+    return x + 1;
+}
+
+fn main() {
+    let mut an_integer = 5;
+    an_integer = test(1) + 3;
+
+    let mut x;
+    x = 1;
+    x = true; // { dg-error "expected .<integer>. got .bool." }
+
+    let call_test = test(1);
+}
diff --git a/gcc/testsuite/rust/compile/break1.rs b/gcc/testsuite/rust/compile/break1.rs
new file mode 100644
index 00000000000..91cabffa894
--- /dev/null
+++ b/gcc/testsuite/rust/compile/break1.rs
@@ -0,0 +1,6 @@
+fn main() {
+    let a;
+    a = 1;
+    break a; // { dg-error "cannot 'break' outside of a loop" }
+    // { dg-error "failed to type resolve expression" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/break2.rs b/gcc/testsuite/rust/compile/break2.rs
new file mode 100644
index 00000000000..5ac806aeb9e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/break2.rs
@@ -0,0 +1,15 @@
+fn main() {
+    let mut a = 1;
+    let mut b = 1;
+
+    let mut c;
+    while b > 10 {
+        if (b == 2) {
+            break b;  // { dg-error "can only break with a value inside 'loop'" }
+            // { dg-error "failed to type resolve expression" "" { target *-*-* } .-1 }
+        }
+        c = a + b;
+        a = b;
+        b = c;
+    }
+}
diff --git a/gcc/testsuite/rust/compile/builtin_macro_compile_error.rs b/gcc/testsuite/rust/compile/builtin_macro_compile_error.rs
new file mode 100644
index 00000000000..9d224406a3e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/builtin_macro_compile_error.rs
@@ -0,0 +1,13 @@
+#[rustc_builtin_macro]
+macro_rules! compile_error {
+  () => {{}};
+}
+
+fn main () {
+  let message = "error message";
+  compile_error! (message); // { dg-error "argument must be a string literal" "" }
+  compile_error! (); // { dg-error "macro takes 1 argument" "" }
+  compile_error! ("a", "b"); // { dg-error "macro takes 1 argument" "" }
+  compile_error! ("expected error message"); // { dg-error "expected error message" }
+  compile_error! ("expected error message",); // { dg-error "expected error message" }
+}
diff --git a/gcc/testsuite/rust/compile/builtin_macro_concat.rs b/gcc/testsuite/rust/compile/builtin_macro_concat.rs
new file mode 100644
index 00000000000..9b878af764d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/builtin_macro_concat.rs
@@ -0,0 +1,17 @@
+#[rustc_builtin_macro]
+macro_rules! concat {
+    () => {{}};
+}
+
+fn main() {
+    let not_literal = "identifier";
+    concat!();
+    concat! (,); // { dg-error "argument must be a constant literal" }
+    concat!(not_literal); // { dg-error "argument must be a constant literal" }
+    concat!("message");
+    concat!("message",);
+    concat!("message", 1, true, false, 1.0, 10usize, 2000u64);
+    concat!("message", 1, true, false, 1.0, 10usize, 2000u64,);
+    concat! ("m", not_literal); // { dg-error "argument must be a constant literal" }
+    concat!(not_literal invalid 'm' !!,); // { dg-error "argument must be a constant literal" }
+}
diff --git a/gcc/testsuite/rust/compile/builtin_macro_env.rs b/gcc/testsuite/rust/compile/builtin_macro_env.rs
new file mode 100644
index 00000000000..289e6db2cf1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/builtin_macro_env.rs
@@ -0,0 +1,20 @@
+#[rustc_builtin_macro]
+macro_rules! env {
+  () => {{}};
+}
+
+fn main () {
+  let message = "error message";
+  env! (message); // { dg-error "argument must be a string literal" "" }
+  env! (); // { dg-error "env! takes 1 or 2 arguments" "" }
+  env! (,); // { dg-error "argument must be a string literal" "" }
+  env! (1); // { dg-error "argument must be a string literal" "" }
+  env! ("NOT_DEFINED"); // { dg-error "environment variable 'NOT_DEFINED' not defined" "" }
+  env! ("NOT_DEFINED",); // { dg-error "environment variable 'NOT_DEFINED' not defined" "" }
+  env! ("NOT_DEFINED", 1); // { dg-error "argument must be a string literal" "" }
+  env! ("NOT_DEFINED", "two", "three"); // { dg-error "env! takes 1 or 2 arguments" "" }
+  env! ("NOT_DEFINED" "expected error message"); // { dg-error "expected token: ','" "" }
+  env! ("NOT_DEFINED", "expected error message"); // { dg-error "expected error message" "" }
+  env! ("NOT_DEFINED", "expected error message",); // { dg-error "expected error message" "" }
+  env! (1, "two"); // { dg-error "argument must be a string literal" "" }
+}
diff --git a/gcc/testsuite/rust/compile/builtin_macro_include_bytes.rs b/gcc/testsuite/rust/compile/builtin_macro_include_bytes.rs
new file mode 100644
index 00000000000..38716d33bcd
--- /dev/null
+++ b/gcc/testsuite/rust/compile/builtin_macro_include_bytes.rs
@@ -0,0 +1,13 @@
+#[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
new file mode 100644
index 00000000000..38f5e3b7334
--- /dev/null
+++ b/gcc/testsuite/rust/compile/builtin_macro_include_str.rs
@@ -0,0 +1,13 @@
+#[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
+}
diff --git a/gcc/testsuite/rust/compile/builtin_macro_not_found.rs b/gcc/testsuite/rust/compile/builtin_macro_not_found.rs
new file mode 100644
index 00000000000..1a3228b9284
--- /dev/null
+++ b/gcc/testsuite/rust/compile/builtin_macro_not_found.rs
@@ -0,0 +1,4 @@
+#[rustc_builtin_macro]
+macro_rules! crabby_crab_carb { // { dg-error "cannot find a built-in macro with name .crabby_crab_carb." }
+    () => {{}};
+}
diff --git a/gcc/testsuite/rust/compile/bytecharstring.rs b/gcc/testsuite/rust/compile/bytecharstring.rs
new file mode 100644
index 00000000000..9242e2c5a0b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/bytecharstring.rs
@@ -0,0 +1,8 @@
+fn main ()
+{
+  let _bc = b'\x80';
+  let _bs = b"foo\x80bar";
+
+  let _c = '\xef';        // { dg-error "out of range" }
+  let _s = "Foo\xEFBar";  // { dg-error "out of range" }
+}
diff --git a/gcc/testsuite/rust/compile/canonical_paths1.rs b/gcc/testsuite/rust/compile/canonical_paths1.rs
new file mode 100644
index 00000000000..193e7b5b698
--- /dev/null
+++ b/gcc/testsuite/rust/compile/canonical_paths1.rs
@@ -0,0 +1,25 @@
+// { dg-additional-options "-w -fdump-tree-gimple -frust-crate=example" }
+struct Foo(i32);
+
+trait TR {
+    fn test(&self) -> i32;
+}
+
+mod A {
+    impl ::Foo {
+        pub fn test(self) {}
+        // { dg-final { scan-tree-dump-times {example::A::<impl example::Foo>::test} 2 gimple } }
+    }
+
+    impl ::TR for ::Foo {
+        fn test(&self) -> i32 {
+            // { dg-final { scan-tree-dump-times {example::A::<impl example::Foo as example::TR>::test} 1 gimple } }
+            self.0
+        }
+    }
+}
+
+pub fn test() {
+    let a = Foo(123);
+    a.test();
+}
diff --git a/gcc/testsuite/rust/compile/cast1.rs b/gcc/testsuite/rust/compile/cast1.rs
new file mode 100644
index 00000000000..74c4b1eaac4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/cast1.rs
@@ -0,0 +1,5 @@
+fn main() {
+    let a: i32 = 123;
+    let b = a as char;
+    // { dg-error "invalid cast .i32. to .char." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/cfg1.rs b/gcc/testsuite/rust/compile/cfg1.rs
new file mode 100644
index 00000000000..6984f04d1b9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/cfg1.rs
@@ -0,0 +1,31 @@
+// { dg-additional-options "-w" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[cfg(A)]
+fn test() {
+    unsafe {
+        let a = "test1\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c);
+    }
+}
+
+#[cfg(B)]
+fn test() {
+    unsafe {
+        let a = "test2\n\0";
+        let b = a as *const str;
+        let c = b as *const i8;
+
+        printf(c);
+    }
+}
+
+fn main() {
+    test();
+    // { dg-error "Cannot find path .test. in this scope" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/cfg2.rs b/gcc/testsuite/rust/compile/cfg2.rs
new file mode 100644
index 00000000000..939384c5b7d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/cfg2.rs
@@ -0,0 +1,13 @@
+// { dg-additional-options "-w -frust-cfg=A" }
+struct Foo;
+impl Foo {
+    #[cfg(not(A))]
+    fn test(&self) {}
+}
+
+fn main() {
+    let a = Foo;
+    a.test();
+    // { dg-error "failed to resolve method for .test." "" { target *-*-* } .-1 }
+    // { dg-error "failed to type resolve expression" "" { target *-*-* } .-2 }
+}
diff --git a/gcc/testsuite/rust/compile/cfg3.rs b/gcc/testsuite/rust/compile/cfg3.rs
new file mode 100644
index 00000000000..d6ffab6bfc6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/cfg3.rs
@@ -0,0 +1,11 @@
+// { dg-additional-options "-w -frust-cfg=A -frust-cfg=B" }
+struct Foo;
+impl Foo {
+    #[cfg(all(A, B))]
+    fn test(&self) {}
+}
+
+fn main() {
+    let a = Foo;
+    a.test();
+}
diff --git a/gcc/testsuite/rust/compile/cfg4.rs b/gcc/testsuite/rust/compile/cfg4.rs
new file mode 100644
index 00000000000..2834c277ddf
--- /dev/null
+++ b/gcc/testsuite/rust/compile/cfg4.rs
@@ -0,0 +1,11 @@
+// { dg-additional-options "-w -frust-cfg=A" }
+struct Foo;
+impl Foo {
+    #[cfg(any(A, B))]
+    fn test(&self) {}
+}
+
+fn main() {
+    let a = Foo;
+    a.test();
+}
diff --git a/gcc/testsuite/rust/compile/cfg5.rs b/gcc/testsuite/rust/compile/cfg5.rs
new file mode 100644
index 00000000000..1852efaf8df
--- /dev/null
+++ b/gcc/testsuite/rust/compile/cfg5.rs
@@ -0,0 +1,11 @@
+// { dg-additional-options "-w -frust-cfg=A=\"B\"" }
+struct Foo;
+impl Foo {
+    #[cfg(A = "B")]
+    fn test(&self) {}
+}
+
+fn main() {
+    let a = Foo;
+    a.test();
+}
diff --git a/gcc/testsuite/rust/compile/compile.exp b/gcc/testsuite/rust/compile/compile.exp
new file mode 100644
index 00000000000..13423d76c92
--- /dev/null
+++ b/gcc/testsuite/rust/compile/compile.exp
@@ -0,0 +1,35 @@
+# Copyright (C) 2021-2022 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/complex-path1.rs b/gcc/testsuite/rust/compile/complex-path1.rs
new file mode 100644
index 00000000000..54011bd6976
--- /dev/null
+++ b/gcc/testsuite/rust/compile/complex-path1.rs
@@ -0,0 +1,18 @@
+// { dg-additional-options "-w" }
+mod a {
+    pub fn foo() {}
+}
+
+mod b {
+    pub fn foo() {
+        super::a::foo();
+    }
+}
+
+mod foo {
+    pub struct bar(pub i32);
+}
+
+fn test() -> crate::foo::bar {
+    foo::bar(123)
+}
diff --git a/gcc/testsuite/rust/compile/const-issue1440.rs b/gcc/testsuite/rust/compile/const-issue1440.rs
new file mode 100644
index 00000000000..9b974b96bbb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const-issue1440.rs
@@ -0,0 +1,76 @@
+// { dg-additional-options "-w" }
+
+mod intrinsics {
+    extern "rust-intrinsic" {
+        pub fn wrapping_add<T>(a: T, b: T) -> T;
+        pub fn rotate_left<T>(a: T, b: T) -> T;
+        pub fn rotate_right<T>(a: T, b: T) -> T;
+        pub fn offset<T>(ptr: *const T, count: isize) -> *const T;
+    }
+}
+
+mod mem {
+    extern "rust-intrinsic" {
+        #[rustc_const_stable(feature = "const_transmute", since = "1.46.0")]
+        pub fn transmute<T, U>(_: T) -> U;
+        pub fn size_of<T>() -> usize;
+    }
+}
+
+macro_rules! impl_uint {
+    ($($ty:ident = $lang:literal),*) => {
+        $(
+            impl $ty {
+                pub fn wrapping_add(self, rhs: Self) -> Self {
+                    // intrinsics::wrapping_add(self, rhs)
+                    self + rhs
+                }
+
+                pub fn rotate_left(self, n: u32) -> Self {
+                    unsafe {
+                        intrinsics::rotate_left(self, n as Self)
+                    }
+                }
+
+                pub fn rotate_right(self, n: u32) -> Self {
+                    unsafe {
+                        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 {
+                    // { dg-error "only functions marked as .const. are allowed to be called from constant contexts" "" { target *-*-* } .-1 }
+                    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 {
+                    // { dg-error "only functions marked as .const. are allowed to be called from constant contexts" "" { target *-*-* } .-1 }
+                    unsafe { mem::transmute(bytes) }
+                }
+            }
+        )*
+    }
+}
+
+impl_uint!(
+    u8 = "u8",
+    u16 = "u16",
+    u32 = "u32",
+    u64 = "u64",
+    u128 = "u128",
+    usize = "usize"
+);
diff --git a/gcc/testsuite/rust/compile/const1.rs b/gcc/testsuite/rust/compile/const1.rs
new file mode 100644
index 00000000000..5f19c674c94
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const1.rs
@@ -0,0 +1,6 @@
+fn bar() {}
+
+const fn foo() {
+    bar(); // { dg-error "only functions marked as .const. are allowed to be called from constant contexts" }
+}
+
diff --git a/gcc/testsuite/rust/compile/const2.rs b/gcc/testsuite/rust/compile/const2.rs
new file mode 100644
index 00000000000..17b6de573dd
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const2.rs
@@ -0,0 +1,7 @@
+// { dg-additional-options "-w" }
+
+const fn foo() {
+    const fn bar() {}
+
+    bar();
+}
diff --git a/gcc/testsuite/rust/compile/const3.rs b/gcc/testsuite/rust/compile/const3.rs
new file mode 100644
index 00000000000..22dc3d356ca
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const3.rs
@@ -0,0 +1,7 @@
+fn size() -> usize {
+    15
+}
+
+fn main() {
+    let a = [15; size()]; // { dg-error "only functions marked as .const. are allowed to be called from constant contexts" }
+}
diff --git a/gcc/testsuite/rust/compile/const_generics_1.rs b/gcc/testsuite/rust/compile/const_generics_1.rs
new file mode 100644
index 00000000000..bcad8ee6a19
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_1.rs
@@ -0,0 +1,19 @@
+// { dg-additional-options "-w" }
+
+// There are errors about unused generic parameters, but we can't handle that yet.
+// Still, this code is invalid Rust.
+
+mod sain {
+    struct Foo<const N: usize>;
+    struct Bar<T, const N: usize>;
+    struct Baz<'l, T, const N: usize>;
+}
+
+mod doux {
+    struct Foo<const N: usize = 15>;
+    struct Bar<T, const N: usize = { 14 * 2 }>;
+
+    const N_DEFAULT: usize = 3;
+
+    struct Baz<'l, T, const N: usize = N_DEFAULT>;
+}
diff --git a/gcc/testsuite/rust/compile/const_generics_2.rs b/gcc/testsuite/rust/compile/const_generics_2.rs
new file mode 100644
index 00000000000..98495cf404d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_2.rs
@@ -0,0 +1,4 @@
+struct Foo<const N>; // { dg-error "expecting .:. but .>. found" }
+struct Bar<const N: >; // { dg-error "unrecognised token .>. in type" }
+struct Baz<const N: usize = >; // { dg-error "invalid token for start of default value for const generic parameter" }
+// { dg-error "unrecognised token .>. in type" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/const_generics_3.rs b/gcc/testsuite/rust/compile/const_generics_3.rs
new file mode 100644
index 00000000000..6a3a0fe27bf
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_3.rs
@@ -0,0 +1,26 @@
+// { dg-additional-options "-w" }
+
+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 "failed to find name: N" }
+}
+
+fn main() {
+    let foo = Foo::<i32> { value: [15] };
+    let foo = Foo::<i32, 2> { value: [15, 13] };
+    let foo: Foo<i32, 2> = Foo { value: [15, 13] };
+    let foo: Foo<i32, 2> = Foo::<i32, 2> { value: [15, 13] };
+    let foo: Foo<i32, { 1 + 1 }> = Foo { value: [15, 13] };
+    let foo = Foo::<i32, { 1 + 1 }> { value: [15, 13] };
+    let foo: Foo<i32, { 1 + 1 }> = Foo::<i32, { 1 + 1 }> { value: [15, 13] };
+    let foo: Foo<i32, M> = Foo::<i32, 4> {
+        value: [15, 13, 11, 9],
+    };
+
+    // FIXME: Add proper const typecheck errors here
+    let invalid_foo: Foo<i32, { 1 + 1 }> = Foo::<i32, 3> { value: [15, 13] };
+    let invalid_foo: Foo<i32, { 1 + 1 }> = Foo::<i32, M> { value: [15, 13] };
+    let invalid_foo: Foo<i32> = Foo::<i32, 2> { value: [15, 13] };
+}
diff --git a/gcc/testsuite/rust/compile/const_generics_4.rs b/gcc/testsuite/rust/compile/const_generics_4.rs
new file mode 100644
index 00000000000..8a3754da433
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_4.rs
@@ -0,0 +1,7 @@
+// { dg-additional-options "-w" }
+
+const P: usize = 14;
+
+struct Foo<const N: usize = { M }>; // { dg-error "failed to find name: M" }
+struct Bar<const N: usize = { P }>;
+struct Baz<const N: NotAType = { P }>; // { dg-error "failed to resolve TypePath: NotAType in this scope" }
diff --git a/gcc/testsuite/rust/compile/const_generics_5.rs b/gcc/testsuite/rust/compile/const_generics_5.rs
new file mode 100644
index 00000000000..5344e31a140
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_5.rs
@@ -0,0 +1,12 @@
+struct Foo<const N: usize = { 14 }>;
+
+const M: usize = 15;
+type N = Foo<3>;
+
+fn main() {
+    let _: Foo<15> = Foo;
+    let _: Foo<{ M }> = Foo;
+    let _: Foo<M> = Foo;
+    // bogus error, but it means the above const generic gets disambiguated properly
+    let _: Foo<N> = Foo; // { dg-error "TypePath Foo<N> declares generic arguments but the type Foo{Foo {}} does not have any" }
+}
diff --git a/gcc/testsuite/rust/compile/const_generics_6.rs b/gcc/testsuite/rust/compile/const_generics_6.rs
new file mode 100644
index 00000000000..de261236d93
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const_generics_6.rs
@@ -0,0 +1,2 @@
+struct Foo<const N: usize>;
+struct Bar<const N: usize = { 15i32 }>; // { dg-error "expected .usize. got .i32." }
diff --git a/gcc/testsuite/rust/compile/continue1.rs b/gcc/testsuite/rust/compile/continue1.rs
new file mode 100644
index 00000000000..994312b52cc
--- /dev/null
+++ b/gcc/testsuite/rust/compile/continue1.rs
@@ -0,0 +1,10 @@
+fn main() {
+    let mut a = 1;
+    let mut b = 1;
+
+    let _fib = {
+        continue; // { dg-error "cannot 'continue' outside of a loop" }
+        // { dg-error "failed to type resolve expression" "" { target *-*-* } .-1 }
+        123
+    };
+}
diff --git a/gcc/testsuite/rust/compile/deadcode_err1.rs b/gcc/testsuite/rust/compile/deadcode_err1.rs
new file mode 100644
index 00000000000..1dbe95731e1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/deadcode_err1.rs
@@ -0,0 +1,11 @@
+fn foo() -> i32 {
+    return 1;
+
+    let mut a = 1; // { dg-warning "unreachable statement" }
+    a = 1.1; // { dg-warning "unreachable statement" }
+    // { dg-error "expected .<integer>. got .<float>." "" { target *-*-* } .-1 }
+}
+
+fn main() {
+    foo();
+}
diff --git a/gcc/testsuite/rust/compile/deadcode_err2.rs b/gcc/testsuite/rust/compile/deadcode_err2.rs
new file mode 100644
index 00000000000..8c0eb4617a7
--- /dev/null
+++ b/gcc/testsuite/rust/compile/deadcode_err2.rs
@@ -0,0 +1,16 @@
+fn foo() -> i32 {
+    return 1;
+    return 1.5; // { dg-error "expected .i32. got .<float>." }
+    // { dg-warning "unreachable statement" "" { target *-*-* } .-1 } 
+}
+
+fn bar() -> i32 {
+    return 1.5; // { dg-error "expected .i32. got .<float>." }
+    return 1;
+    // { dg-warning "unreachable statement" "" { target *-*-* } .-1 } 
+}
+
+fn main() {
+    foo();
+    bar();
+}
diff --git a/gcc/testsuite/rust/compile/debug-diagnostics-default.rs b/gcc/testsuite/rust/compile/debug-diagnostics-default.rs
new file mode 100644
index 00000000000..90b0e575b45
--- /dev/null
+++ b/gcc/testsuite/rust/compile/debug-diagnostics-default.rs
@@ -0,0 +1,5 @@
+// Make sure we don't see any 'note's:
+// { dg-bogus {note: } "" { target *-*-* } 0 }
+
+fn main() {
+}
diff --git a/gcc/testsuite/rust/compile/debug-diagnostics-off.rs b/gcc/testsuite/rust/compile/debug-diagnostics-off.rs
new file mode 100644
index 00000000000..77b82b35e62
--- /dev/null
+++ b/gcc/testsuite/rust/compile/debug-diagnostics-off.rs
@@ -0,0 +1,7 @@
+// { dg-additional-options "-fno-rust-debug" }
+
+// Make sure we don't see any 'note's:
+// { dg-bogus {note: } "" { target *-*-* } 0 }
+
+fn main() {
+}
diff --git a/gcc/testsuite/rust/compile/debug-diagnostics-on.rs b/gcc/testsuite/rust/compile/debug-diagnostics-on.rs
new file mode 100644
index 00000000000..847fd24d7bd
--- /dev/null
+++ b/gcc/testsuite/rust/compile/debug-diagnostics-on.rs
@@ -0,0 +1,7 @@
+// { dg-additional-options "-frust-debug" }
+
+// Just scan for one of the Rust front end debug diagnostics:
+// { dg-message {note: Attempting to parse file: .+/gcc/testsuite/rust/compile/debug-diagnostics-on\.rs} "" { target *-*-* } 0 }
+
+fn main() {
+}
diff --git a/gcc/testsuite/rust/compile/doc_isolated_cr_block_comment.rs b/gcc/testsuite/rust/compile/doc_isolated_cr_block_comment.rs
new file mode 100644
index 00000000000..0ada77f69cf
--- /dev/null
+++ b/gcc/testsuite/rust/compile/doc_isolated_cr_block_comment.rs
@@ -0,0 +1,3 @@
+// { dg-error "Isolated CR" "" { target *-*-* } .+1 }
+/** doc cr
 comment */
+pub fn main () { }
diff --git a/gcc/testsuite/rust/compile/doc_isolated_cr_inner_block_comment.rs b/gcc/testsuite/rust/compile/doc_isolated_cr_inner_block_comment.rs
new file mode 100644
index 00000000000..7db35341bee
--- /dev/null
+++ b/gcc/testsuite/rust/compile/doc_isolated_cr_inner_block_comment.rs
@@ -0,0 +1,5 @@
+pub fn main ()
+{
+// { dg-error "Isolated CR" "" { target *-*-* } .+1 }
+  /*! doc cr
 comment */
+}
diff --git a/gcc/testsuite/rust/compile/doc_isolated_cr_inner_line_comment.rs b/gcc/testsuite/rust/compile/doc_isolated_cr_inner_line_comment.rs
new file mode 100644
index 00000000000..d75da75e218
--- /dev/null
+++ b/gcc/testsuite/rust/compile/doc_isolated_cr_inner_line_comment.rs
@@ -0,0 +1,5 @@
+pub fn main ()
+{
+// { dg-error "Isolated CR" "" { target *-*-* } .+1 }
+  //! doc cr
 comment
+}
diff --git a/gcc/testsuite/rust/compile/doc_isolated_cr_line_comment.rs b/gcc/testsuite/rust/compile/doc_isolated_cr_line_comment.rs
new file mode 100644
index 00000000000..7b6ef989c30
--- /dev/null
+++ b/gcc/testsuite/rust/compile/doc_isolated_cr_line_comment.rs
@@ -0,0 +1,3 @@
+// { dg-error "Isolated CR" "" { target *-*-* } .+1 }
+/// doc cr
 comment
+pub fn main () { }
diff --git a/gcc/testsuite/rust/compile/dup_fields.rs b/gcc/testsuite/rust/compile/dup_fields.rs
new file mode 100644
index 00000000000..ab39955eca0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/dup_fields.rs
@@ -0,0 +1,23 @@
+struct S { a: i32, b: i32, c: u8, a: i128 }
+// { dg-error "duplicate field" "" { target *-*-* } .-1 }
+
+union U
+  {
+    a: i32,
+    b: i32,
+    c: u8,
+    b: char // { dg-error "duplicate field" "" { target *-*-* } }
+  }
+
+fn main ()
+{
+  struct SS { alpha: i32, beta: i32, gamma: u8, gamma: i128 }
+  // { dg-error "duplicate field" "" { target *-*-* } .-1 }
+
+  union UU
+    {
+      alpha: i32, beta: i32,
+      gamma: u8, beta: char
+      // { dg-error "duplicate field" "" { target *-*-* } .-1 }
+    }
+}
diff --git a/gcc/testsuite/rust/compile/empty_comment_before_match.rs b/gcc/testsuite/rust/compile/empty_comment_before_match.rs
new file mode 100644
index 00000000000..3d344d3e758
--- /dev/null
+++ b/gcc/testsuite/rust/compile/empty_comment_before_match.rs
@@ -0,0 +1,7 @@
+fn foo (x: i8) -> i32 { // { dg-warning "function is never used" }
+    //
+    match x {
+        1 => { return 1; }
+        _ => { return 0; }
+    }
+}
diff --git a/gcc/testsuite/rust/compile/expected_type_args2.rs b/gcc/testsuite/rust/compile/expected_type_args2.rs
new file mode 100644
index 00000000000..79454202aad
--- /dev/null
+++ b/gcc/testsuite/rust/compile/expected_type_args2.rs
@@ -0,0 +1,6 @@
+struct Foo<A>(A);
+
+fn main() {
+    let a: Foo = Foo::<i32>(123);
+    // { dg-error "generic item takes at least 1 type arguments but 0 were supplied" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/expected_type_args3.rs b/gcc/testsuite/rust/compile/expected_type_args3.rs
new file mode 100644
index 00000000000..ba07239207a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/expected_type_args3.rs
@@ -0,0 +1,8 @@
+struct Foo<A>(A);
+
+impl Foo {
+    // { dg-error "generic item takes at least 1 type arguments but 0 were supplied" "" { target *-*-* } .-1 }
+    fn test() -> i32 {
+        123
+    }
+}
diff --git a/gcc/testsuite/rust/compile/func1.rs b/gcc/testsuite/rust/compile/func1.rs
new file mode 100644
index 00000000000..6758a3898e3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/func1.rs
@@ -0,0 +1,9 @@
+fn test(x: i32) -> bool {
+    return x + 1; // { dg-error "expected .bool. got .i32." }
+}
+
+fn main() {
+    let an_integer = 5;
+
+    let call_test = test(1);
+}
diff --git a/gcc/testsuite/rust/compile/func2.rs b/gcc/testsuite/rust/compile/func2.rs
new file mode 100644
index 00000000000..0b8d999fec1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/func2.rs
@@ -0,0 +1,7 @@
+fn test(a: i32, b: i32) -> i32 {
+    a + b
+}
+
+fn main() {
+    let a = test(1); // { dg-error "unexpected number of arguments 1 expected 2" }
+}
diff --git a/gcc/testsuite/rust/compile/func3.rs b/gcc/testsuite/rust/compile/func3.rs
new file mode 100644
index 00000000000..2a329476118
--- /dev/null
+++ b/gcc/testsuite/rust/compile/func3.rs
@@ -0,0 +1,9 @@
+fn test(a: i32, b: i32) -> i32 {
+    a + b
+}
+
+fn main() {
+    let a = test(1, true);
+    // { dg-error "expected .i32. got .bool." "" { target *-*-* } .-1 }
+    // { dg-error "Type Resolution failure on parameter" "" { target *-*-* } .-2 }
+}
diff --git a/gcc/testsuite/rust/compile/func4.rs b/gcc/testsuite/rust/compile/func4.rs
new file mode 100644
index 00000000000..3b2d2b0d773
--- /dev/null
+++ b/gcc/testsuite/rust/compile/func4.rs
@@ -0,0 +1,6 @@
+fn func() -> i32 { // { dg-error "expected .i32. got ...." }
+}
+
+fn main() {
+    func();
+}
diff --git a/gcc/testsuite/rust/compile/func5.rs b/gcc/testsuite/rust/compile/func5.rs
new file mode 100644
index 00000000000..05624f524e9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/func5.rs
@@ -0,0 +1,7 @@
+fn func() -> i32 {
+    return; // { dg-error "expected .i32. got ...." }
+}
+
+fn main() {
+    func();
+}
diff --git a/gcc/testsuite/rust/compile/generic-default1.rs b/gcc/testsuite/rust/compile/generic-default1.rs
new file mode 100644
index 00000000000..0a132bf5d6b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/generic-default1.rs
@@ -0,0 +1,7 @@
+struct Foo<A = i321>(A);
+// { dg-error "failed to resolve TypePath: i321" "" { target *-*-* } .-1 }
+
+fn main() {
+    let a;
+    a = Foo(123);
+}
diff --git a/gcc/testsuite/rust/compile/generics1.rs b/gcc/testsuite/rust/compile/generics1.rs
new file mode 100644
index 00000000000..de1bbf5dafb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/generics1.rs
@@ -0,0 +1,11 @@
+// { dg-error "expected .i32. got .i8." "" { target *-*-* } 0 }
+
+struct GenericStruct<T>(T, usize);
+
+fn main() {
+    let a2: GenericStruct<i8>;
+    a2 = GenericStruct::<_>(1, 456);
+
+    let b2: i32 = a2.0;
+    let c2: usize = a2.1;
+}
diff --git a/gcc/testsuite/rust/compile/generics10.rs b/gcc/testsuite/rust/compile/generics10.rs
new file mode 100644
index 00000000000..a734fa8a197
--- /dev/null
+++ b/gcc/testsuite/rust/compile/generics10.rs
@@ -0,0 +1,12 @@
+struct Foo<A, B>(A, B);
+
+impl<X = i32> Foo<X, f32> { // { dg-error "defaults for type parameters are not allowed here" }
+    fn new(a: X, b: f32) -> Self {
+        Self(a, b)
+    }
+}
+
+fn main() {
+    let a;
+    a = Foo::new(123, 456f32);
+}
diff --git a/gcc/testsuite/rust/compile/generics11.rs b/gcc/testsuite/rust/compile/generics11.rs
new file mode 100644
index 00000000000..4d3b9e1777c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/generics11.rs
@@ -0,0 +1,12 @@
+struct Foo<T>(T, bool);
+
+impl<T> Foo<T> {
+    fn test() -> i32 {
+        123
+    }
+}
+
+fn main() {
+    let a = Foo::test();
+    // { dg-error "type annotations needed" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/generics12.rs b/gcc/testsuite/rust/compile/generics12.rs
new file mode 100644
index 00000000000..f1ac8b0314b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/generics12.rs
@@ -0,0 +1,6 @@
+fn main() {
+    bar();
+    // { dg-error "type annotations needed" "" { target *-*-* } .-1 }
+}
+
+fn bar<T>() {}
diff --git a/gcc/testsuite/rust/compile/generics13.rs b/gcc/testsuite/rust/compile/generics13.rs
new file mode 100644
index 00000000000..05c75c5f63d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/generics13.rs
@@ -0,0 +1 @@
+struct Foo<A, 'a>; // { dg-error "invalid order for generic parameters: lifetimes should always come before types" }
diff --git a/gcc/testsuite/rust/compile/generics2.rs b/gcc/testsuite/rust/compile/generics2.rs
new file mode 100644
index 00000000000..5812b133038
--- /dev/null
+++ b/gcc/testsuite/rust/compile/generics2.rs
@@ -0,0 +1,11 @@
+// { dg-error "expected .i32. got .i8." "" { target *-*-* } 0 }
+
+struct GenericStruct<T>(T, usize);
+
+fn main() {
+    let a2: GenericStruct<i8>;
+    a2 = GenericStruct(1, 456);
+
+    let b2: i32 = a2.0;
+    let c2: usize = a2.1;
+}
diff --git a/gcc/testsuite/rust/compile/generics3.rs b/gcc/testsuite/rust/compile/generics3.rs
new file mode 100644
index 00000000000..2d4210588fb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/generics3.rs
@@ -0,0 +1,10 @@
+// { dg-error "expected .i32. got .i8." "" { target *-*-* } 0 }
+struct GenericStruct<T>(T, usize);
+
+fn main() {
+    let a2;
+    a2 = GenericStruct::<i8>(1, 456);
+
+    let b2: i32 = a2.0;
+    let c2: usize = a2.1;
+}
diff --git a/gcc/testsuite/rust/compile/generics4.rs b/gcc/testsuite/rust/compile/generics4.rs
new file mode 100644
index 00000000000..8af13586a37
--- /dev/null
+++ b/gcc/testsuite/rust/compile/generics4.rs
@@ -0,0 +1,16 @@
+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 type resolve expression} "" { target *-*-* } .-1 }
+                                           // { dg-error {Failed to resolve expression of function call} "" { target *-*-* } .-2 }
+                                           // { duplicate _dg-error {failed to type resolve expression} "" { target *-*-* } .-3 }
+
+    let b2: i32 = a2.0;
+    // { dg-error {Expected Tuple or ADT got: T\?} "" { target *-*-* } .-1 }
+    // { dg-error {failed to type resolve expression} "" { target *-*-* } .-2 }
+    let c2: usize = a2.1;
+    // { dg-error {Expected Tuple or ADT got: T\?} "" { target *-*-* } .-1 }
+    // { dg-error {failed to type resolve expression} "" { target *-*-* } .-2 }
+}
diff --git a/gcc/testsuite/rust/compile/generics5.rs b/gcc/testsuite/rust/compile/generics5.rs
new file mode 100644
index 00000000000..6c847b5a29b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/generics5.rs
@@ -0,0 +1,10 @@
+struct GenericStruct<T>(T, usize);
+
+fn main() {
+    let a2;
+    a2 = GenericStruct::<i8, T>(1, 456);
+    // { dg-error "failed to resolve TypePath: 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
new file mode 100644
index 00000000000..3b81e1bbee1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/generics6.rs
@@ -0,0 +1,31 @@
+struct Foo<A> {
+    a: A,
+}
+
+impl Foo<isize> {
+    fn test() -> i32 { // { dg-error "possible candidate" "TODO" { xfail *-*-* } }
+        123
+    }
+
+    fn bar(self) -> isize {
+        self.a
+    }
+}
+
+impl Foo<f32> {
+    fn test() -> i32 { // { dg-error "possible candidate" "TODO" { xfail *-*-* } }
+        123
+    }
+
+    fn bar(self) -> f32 {
+        self.a
+    }
+}
+
+fn main() {
+    let a: i32 = Foo::test(); // { dg-error "multiple applicable items in scope for: test" }
+    // { dg-error {failed to type resolve expression} "" { target *-*-* } .-1 }
+    // { dg-error {Failed to resolve expression of function call} "" { target *-*-* } .-2 }
+    // { duplicate _dg-error {failed to type resolve expression} "" { target *-*-* } .-3 }
+}
+
diff --git a/gcc/testsuite/rust/compile/generics7.rs b/gcc/testsuite/rust/compile/generics7.rs
new file mode 100644
index 00000000000..2a41632e693
--- /dev/null
+++ b/gcc/testsuite/rust/compile/generics7.rs
@@ -0,0 +1,26 @@
+struct Foo<A> {
+    a: A,
+}
+
+impl Foo<isize> {
+    fn bar(self) -> isize { // { dg-error "duplicate definitions with name bar" }
+        self.a
+    }
+}
+
+impl Foo<char> {
+    fn bar(self) -> char { // { dg-error "duplicate definitions with name bar" }
+        self.a
+    }
+}
+
+impl<T> Foo<T> {
+    fn bar(self) -> T {
+        self.a
+    }
+}
+
+fn main() {
+    let a = Foo { a: 123 };
+    a.bar();
+}
diff --git a/gcc/testsuite/rust/compile/generics8.rs b/gcc/testsuite/rust/compile/generics8.rs
new file mode 100644
index 00000000000..ceefc5d2c6a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/generics8.rs
@@ -0,0 +1,15 @@
+struct Foo<A, B>(A, B);
+
+impl<T> Foo<i32, T> {
+    fn test(a: T) -> T {
+        a
+    }
+}
+
+impl Foo<i32, f32> {
+    fn test() -> f32 { // { dg-error "duplicate definitions with name test" }
+        123f32
+    }
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/generics9.rs b/gcc/testsuite/rust/compile/generics9.rs
new file mode 100644
index 00000000000..3766703431e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/generics9.rs
@@ -0,0 +1,10 @@
+struct Foo<A, B = (A, B)>(A, B);
+// { dg-error "failed to resolve TypePath: B" "" { target *-*-* } .-1 }
+
+fn main() {
+    let a: Foo<bool>;
+    a = Foo::<bool>(true, (false, true));
+
+    let b: (bool, bool);
+    b = a.1;
+}
diff --git a/gcc/testsuite/rust/compile/implicit_returns_err1.rs b/gcc/testsuite/rust/compile/implicit_returns_err1.rs
new file mode 100644
index 00000000000..973ba80fb86
--- /dev/null
+++ b/gcc/testsuite/rust/compile/implicit_returns_err1.rs
@@ -0,0 +1,12 @@
+fn test(x: i32) -> i32 {
+    if x > 1 { // { dg-error "expected .... got .<integer>." }
+        1
+    } else {
+        2
+    }
+    3
+}
+
+fn main() {
+    let a = test(1);
+}
diff --git a/gcc/testsuite/rust/compile/implicit_returns_err2.rs b/gcc/testsuite/rust/compile/implicit_returns_err2.rs
new file mode 100644
index 00000000000..fb90748871f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/implicit_returns_err2.rs
@@ -0,0 +1,10 @@
+fn test(x: i32) -> i32 {
+    // { dg-error "expected .i32. got .bool." "" { target *-*-* } .-1 }
+    return 1;
+    // { dg-warning "unreachable expression" "" { target *-*-* } .+1 }
+    true
+}
+
+fn main() {
+    let a = test(1);
+}
diff --git a/gcc/testsuite/rust/compile/implicit_returns_err3.rs b/gcc/testsuite/rust/compile/implicit_returns_err3.rs
new file mode 100644
index 00000000000..37b1c62414c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/implicit_returns_err3.rs
@@ -0,0 +1,9 @@
+fn test(x: i32) -> i32 { // { dg-error "expected .i32. got ...." }
+    if x > 1 {
+        1
+    }
+}
+
+fn main() {
+    let a = test(9);
+}
diff --git a/gcc/testsuite/rust/compile/implicit_returns_err4.rs b/gcc/testsuite/rust/compile/implicit_returns_err4.rs
new file mode 100644
index 00000000000..59c6a020d4c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/implicit_returns_err4.rs
@@ -0,0 +1,10 @@
+fn test(x: bool) -> bool {
+    // { dg-error "expected .bool. got ...." "" { target *-*-*} .-1 }
+    return x;
+    // { dg-warning "unreachable expression" "" { target *-*-* } .+1 }
+    ()
+}
+
+fn main() {
+    let a = test(true);
+}
diff --git a/gcc/testsuite/rust/compile/infer-crate-name.rs b/gcc/testsuite/rust/compile/infer-crate-name.rs
new file mode 100644
index 00000000000..b0c0086c04c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/infer-crate-name.rs
@@ -0,0 +1,7 @@
+// { dg-additional-options "-fdump-tree-gimple" }
+pub fn does_nothing() {}
+fn main() {
+    does_nothing()
+}
+// { dg-final { scan-tree-dump-times {infer_crate_name::does_nothing} 2 gimple } }
+// { dg-final { scan-tree-dump-times {infer_crate_name::main} 1 gimple } }
diff --git a/gcc/testsuite/rust/compile/inline_1.rs b/gcc/testsuite/rust/compile/inline_1.rs
new file mode 100644
index 00000000000..4b0f991765a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/inline_1.rs
@@ -0,0 +1,16 @@
+// { dg-additional-options "-fdump-tree-gimple" }
+#[inline]
+fn test_a() {}
+
+// { dg-final { scan-tree-dump-times {always_inline} 1 gimple } }
+#[inline(always)]
+fn test_b() {}
+
+#[inline(never)]
+fn test_c() {}
+
+fn main() {
+    test_a();
+    test_b();
+    test_c();
+}
diff --git a/gcc/testsuite/rust/compile/inline_2.rs b/gcc/testsuite/rust/compile/inline_2.rs
new file mode 100644
index 00000000000..3665fdac804
--- /dev/null
+++ b/gcc/testsuite/rust/compile/inline_2.rs
@@ -0,0 +1,6 @@
+// { dg-additional-options "-w" }
+#[inline(A)] // { dg-error "unknown inline option" }
+fn test_a() {}
+
+#[inline(A, B)] // { dg-error "invalid number of arguments" }
+fn test_b() {}
diff --git a/gcc/testsuite/rust/compile/issue-1005.rs b/gcc/testsuite/rust/compile/issue-1005.rs
new file mode 100644
index 00000000000..46c85eea91e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1005.rs
@@ -0,0 +1,4 @@
+// { dg-additional-options "-w" }
+impl<T> *const T {
+    fn test(self) {}
+}
diff --git a/gcc/testsuite/rust/compile/issue-1019.rs b/gcc/testsuite/rust/compile/issue-1019.rs
new file mode 100644
index 00000000000..aea86a821c7
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1019.rs
@@ -0,0 +1,19 @@
+trait A<T> {
+    type Output;
+
+    fn test(self, a: &T) -> &Self::Output;
+}
+
+struct Foo<T> {
+    // { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+    start: T,
+    end: T,
+}
+
+impl<X> A<X> for Foo<usize> {
+    type Output = X;
+
+    fn test(self, a: &X) -> &Self::Output {
+        a
+    }
+}
diff --git a/gcc/testsuite/rust/compile/issue-1023.rs b/gcc/testsuite/rust/compile/issue-1023.rs
new file mode 100644
index 00000000000..5a0fe6cf530
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1023.rs
@@ -0,0 +1,4 @@
+// { dg-additional-options "-w" }
+fn foo(e: &str) -> &str {
+    &""
+}
diff --git a/gcc/testsuite/rust/compile/issue-1031.rs b/gcc/testsuite/rust/compile/issue-1031.rs
new file mode 100644
index 00000000000..939f0f981e0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1031.rs
@@ -0,0 +1,17 @@
+extern "rust-intrinsic" {
+    #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
+    pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
+}
+
+#[lang = "const_ptr"]
+impl<T> *const T {
+    pub const unsafe fn offset(self, count: isize) -> *const T {
+        // { dg-warning "associated function is never used" "" { target *-*-* } .-1 }
+        unsafe { offset(self, count) }
+    }
+
+    pub const unsafe fn add(self, count: usize) -> Self {
+        // { dg-warning "associated function is never used" "" { target *-*-* } .-1 }
+        unsafe { self.offset(count as isize) }
+    }
+}
diff --git a/gcc/testsuite/rust/compile/issue-1034.rs b/gcc/testsuite/rust/compile/issue-1034.rs
new file mode 100644
index 00000000000..23d77005452
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1034.rs
@@ -0,0 +1,16 @@
+trait Foo<T> {
+    type Output;
+
+    fn test(self, slice: &T) -> &Self::Output;
+}
+
+struct Bar<T>(T);
+// { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+
+impl<T> Foo<[T]> for Bar<usize> {
+    type Output = [T];
+
+    fn test(self, slice: &[T]) -> &[T] {
+        slice
+    }
+}
diff --git a/gcc/testsuite/rust/compile/issue-1089.rs b/gcc/testsuite/rust/compile/issue-1089.rs
new file mode 100644
index 00000000000..635af293dbb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1089.rs
@@ -0,0 +1,6 @@
+// { dg-additional-options "-w" }
+pub mod test_mod;
+
+fn main() {
+    let a = test_mod::Test(123);
+}
diff --git a/gcc/testsuite/rust/compile/issue-1128.rs b/gcc/testsuite/rust/compile/issue-1128.rs
new file mode 100644
index 00000000000..462426b679d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1128.rs
@@ -0,0 +1,6 @@
+pub trait Hasher {
+    fn write(&mut self, bytes: &[u8]);
+    fn write_u8(&mut self, i: u8) {
+        self.write(&[i])
+    }
+}
diff --git a/gcc/testsuite/rust/compile/issue-1129-1.rs b/gcc/testsuite/rust/compile/issue-1129-1.rs
new file mode 100644
index 00000000000..a15903983f0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1129-1.rs
@@ -0,0 +1,4 @@
+// { dg-additional-options "-w" }
+fn write_u8(i: u8) {
+    let x: &[u8] = &[i];
+}
diff --git a/gcc/testsuite/rust/compile/issue-1129-2.rs b/gcc/testsuite/rust/compile/issue-1129-2.rs
new file mode 100644
index 00000000000..25d30faf4aa
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1129-2.rs
@@ -0,0 +1,22 @@
+// { dg-additional-options "-w" }
+pub trait Hasher {
+    fn finish(&self) -> u64;
+    fn write(&mut self, bytes: &[u8]);
+    fn write_u8(&mut self, i: u8) {
+        self.write(&[i])
+    }
+}
+
+struct SipHasher;
+
+impl Hasher for SipHasher {
+    #[inline]
+    fn write(&mut self, msg: &[u8]) {
+        loop {}
+    }
+
+    #[inline]
+    fn finish(&self) -> u64 {
+        0
+    }
+}
diff --git a/gcc/testsuite/rust/compile/issue-1130.rs b/gcc/testsuite/rust/compile/issue-1130.rs
new file mode 100644
index 00000000000..92200c7cd5f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1130.rs
@@ -0,0 +1,47 @@
+// { dg-additional-options "-w" }
+mod mem {
+    extern "rust-intrinsic" {
+        fn size_of<T>() -> usize;
+        fn transmute<U, V>(_: U) -> V;
+    }
+}
+
+impl u16 {
+    fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
+        unsafe { mem::transmute(self) }
+    }
+}
+
+pub trait Hasher {
+    fn finish(&self) -> u64;
+
+    fn write(&mut self, bytes: &[u8]);
+
+    fn write_u8(&mut self, i: u8) {
+        self.write(&[i])
+    }
+
+    fn write_i8(&mut self, i: i8) {
+        self.write_u8(i as u8)
+    }
+
+    fn write_u16(&mut self, i: u16) {
+        self.write(&i.to_ne_bytes())
+    }
+
+    fn write_i16(&mut self, i: i16) {
+        self.write_u16(i as u16)
+    }
+}
+
+pub struct SipHasher;
+
+impl Hasher for SipHasher {
+    #[inline]
+    fn write(&mut self, msg: &[u8]) {}
+
+    #[inline]
+    fn finish(&self) -> u64 {
+        0
+    }
+}
diff --git a/gcc/testsuite/rust/compile/issue-1131.rs b/gcc/testsuite/rust/compile/issue-1131.rs
new file mode 100644
index 00000000000..fd158abc700
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1131.rs
@@ -0,0 +1,4 @@
+extern "rust-intrinsic" {
+    fn size_of<T>() -> usize;
+    fn offset<T>(dst: *const T, offset: isize) -> *const T;
+}
diff --git a/gcc/testsuite/rust/compile/issue-1152.rs b/gcc/testsuite/rust/compile/issue-1152.rs
new file mode 100644
index 00000000000..18eee9e6b4a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1152.rs
@@ -0,0 +1,8 @@
+fn test() {
+    let f = [0; -4_isize];
+    // { dg-error "expected .usize. got .isize." "" { target *-*-* } .-1 }
+    // { dg-error "failed to type resolve expression" "" { target *-*-* } .-2 }
+    let f = [0_usize; -1_isize];
+    // { dg-error "expected .usize. got .isize." "" { target *-*-* } .-1 }
+    // { dg-error "failed to type resolve expression" "" { target *-*-* } .-2 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-1165.rs b/gcc/testsuite/rust/compile/issue-1165.rs
new file mode 100644
index 00000000000..f5889698d70
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1165.rs
@@ -0,0 +1,5 @@
+struct Foo<T>(T);
+
+fn main() {
+    &Foo(123);
+}
diff --git a/gcc/testsuite/rust/compile/issue-1173.rs b/gcc/testsuite/rust/compile/issue-1173.rs
new file mode 100644
index 00000000000..5c2a9173241
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1173.rs
@@ -0,0 +1,23 @@
+// { dg-additional-options "-w" }
+
+#![feature(intrinsics)]
+
+mod mem {
+    extern "rust-intrinsic" {
+        pub fn transmute<U, V>(_: U) -> V;
+    }
+}
+
+pub trait Hasher {
+    fn write(&mut self, bytes: &[u8]);
+    fn write_u16(&mut self, i: u16) {
+        self.write(unsafe { &mem::transmute::<_, [u8; 2]>(i) })
+    }
+}
+
+pub struct SipHasher;
+
+impl Hasher for SipHasher {
+    #[inline]
+    fn write(&mut self, msg: &[u8]) {}
+}
diff --git a/gcc/testsuite/rust/compile/issue-1226.rs b/gcc/testsuite/rust/compile/issue-1226.rs
new file mode 100644
index 00000000000..f5f9e5ff08d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1226.rs
@@ -0,0 +1,6 @@
+// { dg-additional-options "-w" }
+const TEST: *mut u8 = 123 as *mut u8;
+
+fn test() {
+    let a = TEST;
+}
diff --git a/gcc/testsuite/rust/compile/issue-1234.rs b/gcc/testsuite/rust/compile/issue-1234.rs
new file mode 100644
index 00000000000..c6d5932c004
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1234.rs
@@ -0,0 +1,4 @@
+fn foo() -> u8 {
+    // { dg-warning "function is never used" "" { target *-*-* } .-1 }
+    1u8 << 2u32
+}
diff --git a/gcc/testsuite/rust/compile/issue-1235.rs b/gcc/testsuite/rust/compile/issue-1235.rs
new file mode 100644
index 00000000000..098b337455f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1235.rs
@@ -0,0 +1,21 @@
+// { dg-additional-options "-w" }
+struct FatPtr<T> {
+    data: *const T,
+    len: usize,
+}
+
+pub union Repr<T> {
+    rust: *const [T],
+    rust_mut: *mut [T],
+    raw: FatPtr<T>,
+}
+
+impl<T> [T] {
+    pub const fn is_empty(&self) -> bool {
+        self.len() == 0
+    }
+
+    pub const fn len(&self) -> usize {
+        unsafe { Repr { rust: self }.raw.len }
+    }
+}
diff --git a/gcc/testsuite/rust/compile/issue-1237.rs b/gcc/testsuite/rust/compile/issue-1237.rs
new file mode 100644
index 00000000000..542be897949
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1237.rs
@@ -0,0 +1,23 @@
+// { dg-additional-options "-w" }
+mod intrinsics {
+    extern "rust-intrinsic" {
+        pub fn offset<T>(ptr: *const T, count: isize) -> *const T;
+    }
+}
+
+impl<T> *const T {
+    pub unsafe fn offset(self, count: isize) -> *const T {
+        unsafe { intrinsics::offset(self, count) }
+    }
+}
+
+impl<T> [T] {
+    pub unsafe fn get_unchecked(&self, index: usize) -> &T {
+        unsafe { &*(self as *const [T] as *const T).offset(index as isize) }
+    }
+}
+
+#[inline]
+unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 {
+    (unsafe { *buf.get_unchecked(start) } as u64)
+}
diff --git a/gcc/testsuite/rust/compile/issue-1251.rs b/gcc/testsuite/rust/compile/issue-1251.rs
new file mode 100644
index 00000000000..b16e1e0b0d9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1251.rs
@@ -0,0 +1,14 @@
+// { dg-additional-options "-w" }
+mod a {
+    pub mod b {
+        pub mod a {
+            pub fn foo() {}
+        }
+    }
+
+    pub fn bidule() {
+        crate::a::b::a::foo()
+    }
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-1271.rs b/gcc/testsuite/rust/compile/issue-1271.rs
new file mode 100644
index 00000000000..5dd6418de4c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1271.rs
@@ -0,0 +1,5 @@
+// { dg-additional-options "-w" }
+fn test() {
+    let a: &str = "TEST 1";
+    let b: &str = &"TEST 2";
+}
diff --git a/gcc/testsuite/rust/compile/issue-1289.rs b/gcc/testsuite/rust/compile/issue-1289.rs
new file mode 100644
index 00000000000..343aaab078b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1289.rs
@@ -0,0 +1,43 @@
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+mod intrinsics {
+    extern "rust-intrinsic" {
+        #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
+        pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
+    }
+}
+
+#[lang = "mut_ptr"]
+impl<T> *mut T {
+    pub const unsafe fn offset(self, count: isize) -> *mut T {
+        unsafe { intrinsics::offset(self, count) as *mut T }
+    }
+
+    pub const unsafe fn add(self, count: usize) -> Self {
+        unsafe { self.offset(count as isize) }
+    }
+}
+
+#[lang = "const_ptr"]
+impl<T> *const T {
+    pub const unsafe fn offset(self, count: isize) -> *mut T {
+        // { dg-warning "associated function is never used" "" { target *-*-* } .-1 }
+        unsafe { intrinsics::offset(self, count) as *mut T }
+    }
+
+    pub const unsafe fn add(self, count: usize) -> Self {
+        // { dg-warning "associated function is never used" "" { target *-*-* } .-1 }
+        unsafe { self.offset(count as isize) }
+    }
+}
+
+fn main() -> i32 {
+    let a: *mut _ = &mut 123;
+    unsafe {
+        let _b = a.add(123);
+    }
+
+    0
+}
diff --git a/gcc/testsuite/rust/compile/issue-1323-1.rs b/gcc/testsuite/rust/compile/issue-1323-1.rs
new file mode 100644
index 00000000000..a6174253a21
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1323-1.rs
@@ -0,0 +1,18 @@
+fn main() {
+    let mut x = [1, 2, 3];
+    let y: i32 = x[0];
+    print_int(y);
+}
+
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+fn print_int(value: i32) {
+    let s = "%d\n\0";
+    let s_p = s as *const str;
+    let c_p = s_p as *const i8;
+    unsafe {
+        printf(c_p, value as isize);
+    }
+}
diff --git a/gcc/testsuite/rust/compile/issue-1323-2.rs b/gcc/testsuite/rust/compile/issue-1323-2.rs
new file mode 100644
index 00000000000..45168b22fa7
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1323-2.rs
@@ -0,0 +1,16 @@
+fn print_int(value: i32) {
+    let s = "%d\n\0";
+    let s_p = s as *const str;
+    let c_p = s_p as *const i8;
+    unsafe {
+        printf(c_p, value as isize);
+    }
+}
+
+fn main() {
+    print_int(5);
+}
+
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
diff --git a/gcc/testsuite/rust/compile/issue-1383.rs b/gcc/testsuite/rust/compile/issue-1383.rs
new file mode 100644
index 00000000000..cca12e8fc71
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1383.rs
@@ -0,0 +1,8 @@
+pub fn generic_function<X>(a: X) -> X {
+    a
+}
+
+fn main() -> i32 {
+    let a = generic_function(123);
+    a - 123
+}
diff --git a/gcc/testsuite/rust/compile/issue-1393.rs b/gcc/testsuite/rust/compile/issue-1393.rs
new file mode 100644
index 00000000000..e09f01b62e5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1393.rs
@@ -0,0 +1,13 @@
+fn tst() {
+    let a = 123;
+    let b = 0;
+    let _c = if b == 0 {
+        (a & 0x7fffff) << 1
+    } else {
+        (a & 0x7fffff) | 0x800000
+    };
+}
+
+fn main() {
+    tst()
+}
diff --git a/gcc/testsuite/rust/compile/issue-1447.rs b/gcc/testsuite/rust/compile/issue-1447.rs
new file mode 100644
index 00000000000..e0543e6247c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1447.rs
@@ -0,0 +1,28 @@
+// { dg-options "-w" }
+struct PhantomData<T>;
+
+struct Hasher<S> {
+    _marker: PhantomData<S>,
+}
+
+struct Sip24Rounds;
+
+struct SipHasher24 {
+    hasher: Hasher<Sip24Rounds>,
+}
+
+impl SipHasher24 {
+    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher24 {
+        SipHasher24 {
+            hasher: Hasher::new_with_keys(),
+        }
+    }
+}
+
+impl<S> Hasher<S> {
+    fn new_with_keys() -> Hasher<S> {
+        Hasher {
+            _marker: PhantomData,
+        }
+    }
+}
diff --git a/gcc/testsuite/rust/compile/issue-407-2.rs b/gcc/testsuite/rust/compile/issue-407-2.rs
new file mode 100644
index 00000000000..cb8027b9c7f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-407-2.rs
@@ -0,0 +1,21 @@
+// #407
+pub fn loopy()  {
+    let mut a = 1;
+    // { dg-error {failed to parse expr with block in parsing expr statement} "" { target *-*-* } .+2 }
+    // { dg-error {failed to parse statement or expression without block in block expression} "" { target *-*-* } .+1 }
+    loop {
+        // { dg-error {failed to parse expr with block in parsing expr statement} "" { target *-*-* } .+2 }
+        // { dg-error {failed to parse statement or expression without block in block expression} "" { target *-*-* } .+1 }
+	if a < 40 {
+	    a + = 1; // { dg-error "found unexpected token '=' in null denotation" }
+            // { dg-error {failed to parse expression for expression without block \(pratt-parsed expression is null\)} "" { target *-*-* } .-1 }
+            // { dg-error {failed to parse statement or expression without block in block expression} "" { target *-*-* } .-2 }
+            // { dg-error {failed to parse if body block expression in if expression} "" { target *-*-* } .-3 }
+            // { dg-error {could not parse loop body in \(infinite\) loop expression} "" { target *-*-* } .+1 }
+	} else {
+	    break;
+	}
+    }
+}
+// { dg-error {unrecognised token '\}' for start of item} "" { target *-*-* } .-1 }
+// { dg-error {failed to parse item in crate} "" { target *-*-* } .-2 }
diff --git a/gcc/testsuite/rust/compile/issue-407.rs b/gcc/testsuite/rust/compile/issue-407.rs
new file mode 100644
index 00000000000..530b7ddfc12
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-407.rs
@@ -0,0 +1,9 @@
+// This already worked before the #409 code changes.
+fn test()  {
+    let mut a = 1;
+    a + = 1; // { dg-error "found unexpected token '=' in null denotation" }
+    // { dg-error {failed to parse expression for expression without block \(pratt-parsed expression is null\)} "" { target *-*-* } .-1 }
+    // { dg-error {failed to parse statement or expression without block in block expression} "" { target *-*-* } .-2 }
+    // { dg-error {unrecognised token 'integer literal' for start of item} "" { target *-*-* } .-3 }
+    // { dg-error {failed to parse item in crate} "" { target *-*-* } .-4 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-557.rs b/gcc/testsuite/rust/compile/issue-557.rs
new file mode 100644
index 00000000000..aeb5ba6755b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-557.rs
@@ -0,0 +1,4 @@
+// { dg-additional-options "-w" }
+fn test(a: i32, _: i32) {
+    let _ = 42 + a;
+}
diff --git a/gcc/testsuite/rust/compile/issue-635-1.rs b/gcc/testsuite/rust/compile/issue-635-1.rs
new file mode 100644
index 00000000000..dc6a4c2eece
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-635-1.rs
@@ -0,0 +1,5 @@
+// { dg-additional-options "-w" }
+fn test() -> i32 {
+    return 10000000000000000000000000000000000000000000;
+    // { dg-error "integer overflows the respective type .i32." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-635-2.rs b/gcc/testsuite/rust/compile/issue-635-2.rs
new file mode 100644
index 00000000000..335218aa52c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-635-2.rs
@@ -0,0 +1,5 @@
+// { dg-additional-options "-w" }
+fn test() -> f32 {
+    return 10000000000000000000000000000000000000000000.0f32;
+    // { dg-error "decimal overflows the respective type .f32." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/lookup_err1.rs b/gcc/testsuite/rust/compile/lookup_err1.rs
new file mode 100644
index 00000000000..4a96f9ff140
--- /dev/null
+++ b/gcc/testsuite/rust/compile/lookup_err1.rs
@@ -0,0 +1,7 @@
+fn test() {
+    fn nested() {}
+}
+
+fn main() {
+    nested(); // { dg-error "Cannot find path .nested. in this scope" }
+}
diff --git a/gcc/testsuite/rust/compile/macro-issue1053-2.rs b/gcc/testsuite/rust/compile/macro-issue1053-2.rs
new file mode 100644
index 00000000000..31459907c08
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro-issue1053-2.rs
@@ -0,0 +1,5 @@
+macro_rules! m {
+    ($e:expr $(forbidden)*) => {{}}; // { dg-error "token .identifier. is not allowed after .expr. fragment" }
+                                     // { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-1 }
+                                     // { dg-error "failed to parse item in crate" "" { target *-*-* } .-2 }
+}
diff --git a/gcc/testsuite/rust/compile/macro-issue1053.rs b/gcc/testsuite/rust/compile/macro-issue1053.rs
new file mode 100644
index 00000000000..1e968496e0c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro-issue1053.rs
@@ -0,0 +1,3 @@
+macro_rules! m {
+    ($e:expr $(,)*) => {{}};
+}
diff --git a/gcc/testsuite/rust/compile/macro-issue1224.rs b/gcc/testsuite/rust/compile/macro-issue1224.rs
new file mode 100644
index 00000000000..003bbcd5067
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro-issue1224.rs
@@ -0,0 +1,9 @@
+macro_rules! impl_uint {
+    ($($ty:ident),*) => {
+        impl $ty {} // { dg-error "metavariable is still repeating at this depth" }
+                    // { dg-error "unrecognised token" "" { target *-*-* } .-1 } // Spurious
+                    // { dg-error "could not parse type" "" { target *-*-* } .-2 } // Spurious
+    };
+}
+
+impl_uint!(u8, u16, u32, u64, u128);
diff --git a/gcc/testsuite/rust/compile/macro-issue1233.rs b/gcc/testsuite/rust/compile/macro-issue1233.rs
new file mode 100644
index 00000000000..7fab787b9e8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro-issue1233.rs
@@ -0,0 +1,22 @@
+// { dg-additional-options "-frust-cfg=A -w" }
+
+macro_rules! impl_uint {
+    ($($ty:ident = $lang:literal),*) => {
+        $(
+            impl $ty {
+                pub fn to_le(self) -> Self {
+                    #[cfg(not(A))]
+                    {
+                        self
+                    }
+                    #[cfg(A)]
+                    {
+                        self
+                    }
+                }
+            }
+        )*
+    }
+}
+
+impl_uint!(u8 = "u8", u16 = "u16", u32 = "u32");
diff --git a/gcc/testsuite/rust/compile/macro-issue1395-2.rs b/gcc/testsuite/rust/compile/macro-issue1395-2.rs
new file mode 100644
index 00000000000..1df6a3a0038
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro-issue1395-2.rs
@@ -0,0 +1,7 @@
+// { dg-additional-options "-frust-edition=2018" }
+
+macro_rules! try {
+    // { dg-error "expecting .identifier. but .try. found" "" { target *-*-* } .-1 }
+    // { dg-error "failed to parse item in crate" "" { target *-*-* } .-2 }
+    () => {};
+}
diff --git a/gcc/testsuite/rust/compile/macro-issue1395.rs b/gcc/testsuite/rust/compile/macro-issue1395.rs
new file mode 100644
index 00000000000..b0368c1610f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro-issue1395.rs
@@ -0,0 +1,5 @@
+// Default edition is 2015 - this is valid
+
+macro_rules! try {
+    () => {};
+}
diff --git a/gcc/testsuite/rust/compile/macro-issue1400-2.rs b/gcc/testsuite/rust/compile/macro-issue1400-2.rs
new file mode 100644
index 00000000000..ba7b61b0b16
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro-issue1400-2.rs
@@ -0,0 +1,32 @@
+macro_rules! foo {
+    ( ( $( $Trait: ident ),+ ) for $($Ty: ident)* ) => {
+        $(
+            impl $Trait for $Ty {
+    // { dg-error "different amount of matches used in merged repetitions: expected 4, got 1" "" { target *-*-* } .-1 }
+                fn bar() -> i32 {
+                    14
+                }
+            }
+        )+
+    }
+}
+
+trait Foo {
+    fn bar() -> i32;
+}
+
+trait Bar {
+    fn bar() -> i32;
+}
+
+trait Baz {
+    fn bar() -> i32;
+}
+
+trait Qux {
+    fn bar() -> i32;
+}
+
+struct S;
+
+foo! {(Foo, Bar, Baz, Qux) for S}
diff --git a/gcc/testsuite/rust/compile/macro-issue1400.rs b/gcc/testsuite/rust/compile/macro-issue1400.rs
new file mode 100644
index 00000000000..971bd778054
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro-issue1400.rs
@@ -0,0 +1,33 @@
+// { dg-additional-options "-w" }
+
+macro_rules! foo {
+    ( ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
+        $(
+            impl $Trait for $Ty {
+                fn bar() -> i32 {
+                    14
+                }
+            }
+        )+
+    }
+}
+
+trait Foo {
+    fn bar() -> i32;
+}
+
+trait Bar {
+    fn bar() -> i32;
+}
+
+trait Baz {
+    fn bar() -> i32;
+}
+
+trait Qux {
+    fn bar() -> i32;
+}
+
+struct S;
+
+foo! {(Foo, Bar, Baz, Qux) for S}
diff --git a/gcc/testsuite/rust/compile/macro1.rs b/gcc/testsuite/rust/compile/macro1.rs
new file mode 100644
index 00000000000..8cd941891d0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro1.rs
@@ -0,0 +1,3 @@
+macro_rules! empty_parens {
+    () => ();
+}
diff --git a/gcc/testsuite/rust/compile/macro10.rs b/gcc/testsuite/rust/compile/macro10.rs
new file mode 100644
index 00000000000..3f1453e2eda
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro10.rs
@@ -0,0 +1,11 @@
+// { dg-additional-options "-w" }
+macro_rules! foo {
+    {} => {
+        15
+    };
+}
+
+fn main() {
+    let a = foo!();
+    let b = foo![];
+}
diff --git a/gcc/testsuite/rust/compile/macro11.rs b/gcc/testsuite/rust/compile/macro11.rs
new file mode 100644
index 00000000000..97b89a12d84
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro11.rs
@@ -0,0 +1,11 @@
+macro_rules! call_f {
+    ($($f:ident)*) => { $($f();)* }
+}
+
+fn f() {}
+
+// This is valid and should parse items
+fn main() {
+    call_f!(f f f f);
+}
+
diff --git a/gcc/testsuite/rust/compile/macro12.rs b/gcc/testsuite/rust/compile/macro12.rs
new file mode 100644
index 00000000000..b75fbad2c2f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro12.rs
@@ -0,0 +1,8 @@
+// { dg-additional-options "-w" }
+macro_rules! define_vars {
+    ($($v:ident)*) => { $(let $v = 15;)* }
+}
+
+fn main() {
+    define_vars!(a0 b f __some_identifier);
+}
diff --git a/gcc/testsuite/rust/compile/macro13.rs b/gcc/testsuite/rust/compile/macro13.rs
new file mode 100644
index 00000000000..eb8dfbbf393
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro13.rs
@@ -0,0 +1,12 @@
+// { dg-additional-options "-w" }
+macro_rules! create_type {
+    ($s:ident) => {
+        struct $s;
+    };
+}
+
+fn main() {
+    create_type!(A);
+
+    let a = A;
+}
diff --git a/gcc/testsuite/rust/compile/macro14.rs b/gcc/testsuite/rust/compile/macro14.rs
new file mode 100644
index 00000000000..b18c56eefc8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro14.rs
@@ -0,0 +1,10 @@
+// { dg-additional-options "-w" }
+macro_rules! define_vars {
+    ($($v:ident)*) => { $(let $v = 15;)* }
+}
+
+fn main() -> i32 {
+    define_vars!(a0 b f __some_identifier);
+
+    b
+}
diff --git a/gcc/testsuite/rust/compile/macro15.rs b/gcc/testsuite/rust/compile/macro15.rs
new file mode 100644
index 00000000000..02c739e415e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro15.rs
@@ -0,0 +1,12 @@
+// { dg-additional-options "-w" }
+macro_rules! create_type {
+    ($s:ident) => {
+        struct $s;
+    };
+}
+
+create_type!(SomeOuterType);
+
+fn main() {
+    let a = SomeOuterType;
+}
diff --git a/gcc/testsuite/rust/compile/macro16.rs b/gcc/testsuite/rust/compile/macro16.rs
new file mode 100644
index 00000000000..e5e56ed3f03
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro16.rs
@@ -0,0 +1,11 @@
+fn main() {
+    macro_rules! create_type {
+        ($s:ident) => {
+            struct $s(i32);
+        };
+    }
+
+    create_type!(Wrapper);
+
+    let _ = Wrapper(15);
+}
diff --git a/gcc/testsuite/rust/compile/macro17.rs b/gcc/testsuite/rust/compile/macro17.rs
new file mode 100644
index 00000000000..743216529b7
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro17.rs
@@ -0,0 +1,10 @@
+macro_rules! rep {
+    ($a:literal) => { $a }; // { dg-error "reached recursion limit" }
+    ($a:literal $(, $e:literal)*) => { // { dg-error "reached recursion limit" }
+        $a + rep!(0 $(, $e)*) // { dg-error "Failed to match" }
+    }
+}
+
+fn main() -> i32 {
+    rep!(1, 2)
+}
diff --git a/gcc/testsuite/rust/compile/macro18.rs b/gcc/testsuite/rust/compile/macro18.rs
new file mode 100644
index 00000000000..5418725b619
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro18.rs
@@ -0,0 +1,14 @@
+// { dg-additional-options "-w" }
+
+macro_rules! take_stmt {
+    ($s:stmt) => {
+        $s;
+    };
+}
+
+fn main() -> i32 {
+    take_stmt!(let complete = 15;); // { dg-error "Failed to match any rule within macro" }
+    take_stmt!(let lacking = 14);
+
+    0
+}
diff --git a/gcc/testsuite/rust/compile/macro19.rs b/gcc/testsuite/rust/compile/macro19.rs
new file mode 100644
index 00000000000..1bf9a2bfa9d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro19.rs
@@ -0,0 +1,19 @@
+// { dg-additional-options "-w" }
+
+macro_rules! call_without_semi {
+    () => {
+        f()
+    };
+    (block) => {{
+        f()
+    }};
+}
+
+fn f() {}
+
+fn main() -> i32 {
+    call_without_semi!();
+    call_without_semi!(block);
+
+    0
+}
diff --git a/gcc/testsuite/rust/compile/macro2.rs b/gcc/testsuite/rust/compile/macro2.rs
new file mode 100644
index 00000000000..a437655ef70
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro2.rs
@@ -0,0 +1,3 @@
+macro_rules! empty_brackets {
+    [] => [];
+}
diff --git a/gcc/testsuite/rust/compile/macro20.rs b/gcc/testsuite/rust/compile/macro20.rs
new file mode 100644
index 00000000000..9f3cbca012c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro20.rs
@@ -0,0 +1,16 @@
+macro_rules! define_trait {
+    ($assoc:ident, $i:item) => {
+        type $assoc;
+
+        $i
+    };
+}
+
+trait DefinedThroughMacros {
+    define_trait!(
+        Inner,
+        fn takes_inner(i: Self::Inner) -> Self::Inner {
+            i
+        }
+    );
+}
diff --git a/gcc/testsuite/rust/compile/macro21.rs b/gcc/testsuite/rust/compile/macro21.rs
new file mode 100644
index 00000000000..9a1d773ec4b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro21.rs
@@ -0,0 +1,9 @@
+macro_rules! c_fn {
+    {$name:ident ($($arg_name:ident $arg_ty:ty),*) -> $ret_ty:ty} => {
+        fn $name($($arg_name: $arg_ty)*) -> $ret_ty;
+    };
+}
+
+extern "C" {
+    c_fn! {puts (s *const i8) -> i64}
+}
diff --git a/gcc/testsuite/rust/compile/macro22.rs b/gcc/testsuite/rust/compile/macro22.rs
new file mode 100644
index 00000000000..bdc4bada270
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro22.rs
@@ -0,0 +1,10 @@
+macro_rules! print {
+    () => {
+        fn puts(s: *const i8);
+        fn printf(fmt: *const i8, ...);
+    };
+}
+
+extern "C" {
+    print! {}
+}
diff --git a/gcc/testsuite/rust/compile/macro23.rs b/gcc/testsuite/rust/compile/macro23.rs
new file mode 100644
index 00000000000..afaca9bc96b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro23.rs
@@ -0,0 +1,25 @@
+macro_rules! maybe_impl {
+    ($left:ident, $right:ident, $l_fn:ident, $r_fn:ident) => {
+        fn $l_fn(value: T) -> Maybe<T> {
+            Maybe::$left(value)
+        }
+
+        fn $r_fn() -> Maybe<T> {
+            Maybe::$right
+        }
+    };
+}
+
+enum Maybe<T> {
+    Just(T),
+    Nothing,
+}
+
+impl<T> Maybe<T> {
+    maybe_impl!(Just, Nothing, just, nothing);
+}
+
+fn main() {
+    let _ = Maybe::just(14);
+    let _: Maybe<i32> = Maybe::nothing();
+}
diff --git a/gcc/testsuite/rust/compile/macro25.rs b/gcc/testsuite/rust/compile/macro25.rs
new file mode 100644
index 00000000000..d92534c0747
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro25.rs
@@ -0,0 +1,9 @@
+macro_rules! valid {
+    ($($a:literal)* $i:ident) => {{}};
+}
+
+fn main() {
+    valid!(1 one_lit);
+    valid!(identifier_only);
+    valid!(1 2 two_lits);
+}
diff --git a/gcc/testsuite/rust/compile/macro26.rs b/gcc/testsuite/rust/compile/macro26.rs
new file mode 100644
index 00000000000..f6588e75eb0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro26.rs
@@ -0,0 +1,10 @@
+macro_rules! repeat {
+    ( $( $i:literal ),* ; $( $j:literal ),* ) => (( $( ($i,$j) ),* ))
+    // { dg-error "different amount of matches used in merged repetitions" "" { target *-*-* } .-1 }
+}
+
+fn main() -> i32 {
+    let _ = repeat!(1, 2, 3; 2, 3);
+
+    0
+}
diff --git a/gcc/testsuite/rust/compile/macro27.rs b/gcc/testsuite/rust/compile/macro27.rs
new file mode 100644
index 00000000000..ee7833be0a6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro27.rs
@@ -0,0 +1,8 @@
+macro_rules! m {
+    ($a:expr tok) => {
+        // { dg-error "token .identifier. is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
+        // { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-2 }
+        // { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
+        $a
+    };
+}
diff --git a/gcc/testsuite/rust/compile/macro28.rs b/gcc/testsuite/rust/compile/macro28.rs
new file mode 100644
index 00000000000..8002f284ecf
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro28.rs
@@ -0,0 +1,8 @@
+macro_rules! m {
+    ($a:expr $(tok $es:expr)*) => {
+        // { dg-error "token .identifier. is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
+        // { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-2 }
+        // { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
+        $a
+    };
+}
diff --git a/gcc/testsuite/rust/compile/macro29.rs b/gcc/testsuite/rust/compile/macro29.rs
new file mode 100644
index 00000000000..39f5021b74f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro29.rs
@@ -0,0 +1,8 @@
+macro_rules! m {
+    ($($es:expr)* tok) => {
+        // { dg-error "token .identifier. is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
+        // { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-2 }
+        // { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
+        $a
+    };
+}
diff --git a/gcc/testsuite/rust/compile/macro3.rs b/gcc/testsuite/rust/compile/macro3.rs
new file mode 100644
index 00000000000..e5d3e93e07b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro3.rs
@@ -0,0 +1,3 @@
+macro_rules! empty_curlies {
+    {} => {};
+}
diff --git a/gcc/testsuite/rust/compile/macro30.rs b/gcc/testsuite/rust/compile/macro30.rs
new file mode 100644
index 00000000000..35064bc0ee5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro30.rs
@@ -0,0 +1,8 @@
+macro_rules! m {
+    ($e:expr $f:expr) => {
+        // { dg-error "fragment is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
+        // { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-2 }
+        // { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
+        $e
+    };
+}
diff --git a/gcc/testsuite/rust/compile/macro31.rs b/gcc/testsuite/rust/compile/macro31.rs
new file mode 100644
index 00000000000..6674a5fe554
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro31.rs
@@ -0,0 +1,8 @@
+macro_rules! m {
+    ($($e:expr)* $($f:expr)*) => {
+        // { dg-error "fragment is not allowed after .expr. fragment" "" { target *-*-* } .-1 }
+        // { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-2 }
+        // { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 }
+        $e
+    };
+}
diff --git a/gcc/testsuite/rust/compile/macro32.rs b/gcc/testsuite/rust/compile/macro32.rs
new file mode 100644
index 00000000000..d1d6305e6bd
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro32.rs
@@ -0,0 +1,19 @@
+macro_rules! s {
+    ($s:stmt) => {{}};
+}
+
+macro_rules! multi_s {
+    ($($s:stmt)+) => {{}};
+}
+
+fn main() -> i32 {
+    s!(let a = 15);
+    s!(;); // Empty statement
+    s!(let a = 15;); // { dg-error "Failed to match any rule within macro" }
+    multi_s!(let a = 15;);
+    // ^ this actually gets parsed as two statements - one LetStmt and one
+    // empty statement. This is the same behavior as rustc, which you can
+    // see using a count!() macro
+
+    32
+}
diff --git a/gcc/testsuite/rust/compile/macro33.rs b/gcc/testsuite/rust/compile/macro33.rs
new file mode 100644
index 00000000000..2ccd33e50d3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro33.rs
@@ -0,0 +1,5 @@
+macro_rules! forbidden_frag {
+    ($t:ty $not_block:ident) => {{}}; // { dg-error "fragment specifier .ident. is not allowed after .ty. fragments" }
+                                      // { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-1 }
+                                      // { dg-error "failed to parse item in crate" "" { target *-*-* } .-2 }
+}
diff --git a/gcc/testsuite/rust/compile/macro34.rs b/gcc/testsuite/rust/compile/macro34.rs
new file mode 100644
index 00000000000..105d042fd50
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro34.rs
@@ -0,0 +1,3 @@
+macro_rules! allowed_after_expr_matcher {
+    (($t:expr) bok) => {{}}; // follow-set restrictions do not apply after a matcher, but they do apply inside the matcher
+}
diff --git a/gcc/testsuite/rust/compile/macro35.rs b/gcc/testsuite/rust/compile/macro35.rs
new file mode 100644
index 00000000000..07b157b53c2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro35.rs
@@ -0,0 +1,7 @@
+macro_rules! inside_matcher {
+    (($e:expr tok) tok) => {{}}; // { dg-error "token .identifier. is not allowed after .expr. fragment" }
+                                 // { dg-error "failed to parse macro matcher" "" { target *-*-* } .-1 }
+                                 // { dg-error "failed to parse macro match" "" { target *-*-* } .-2 }
+                                 // { dg-error "required first macro rule" "" { target *-*-* } .-3 }
+                                 // { dg-error "failed to parse item in crate" "" { target *-*-* } .-4 }
+}
diff --git a/gcc/testsuite/rust/compile/macro36.rs b/gcc/testsuite/rust/compile/macro36.rs
new file mode 100644
index 00000000000..e5d66b22b7b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro36.rs
@@ -0,0 +1,3 @@
+macro_rules! ty_allowed {
+    ($t:ty $b:block) => {{}};
+}
diff --git a/gcc/testsuite/rust/compile/macro37.rs b/gcc/testsuite/rust/compile/macro37.rs
new file mode 100644
index 00000000000..5713d90130a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro37.rs
@@ -0,0 +1,5 @@
+macro_rules! invalid_after_zeroable {
+    ($e:expr $(,)* forbidden) => {{}}; // { dg-error "token .identifier. is not allowed after .expr. fragment" }
+                                       // { dg-error "required first macro rule" "" { target *-*-* } .-1 }
+                                       // { dg-error "failed to parse item in crate" "" { target *-*-* } .-2 }
+}
diff --git a/gcc/testsuite/rust/compile/macro38.rs b/gcc/testsuite/rust/compile/macro38.rs
new file mode 100644
index 00000000000..eb294aec83b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro38.rs
@@ -0,0 +1,5 @@
+macro_rules! invalid_after_zeroable_multi {
+    ($e:expr $(,)? $(;)* $(=>)? forbidden) => {{}}; // { dg-error "token .identifier. is not allowed after .expr. fragment" }
+                                                    // { dg-error "required first macro rule" "" { target *-*-* } .-1 }
+                                                    // { dg-error "failed to parse item in crate" "" { target *-*-* } .-2 }
+}
diff --git a/gcc/testsuite/rust/compile/macro39.rs b/gcc/testsuite/rust/compile/macro39.rs
new file mode 100644
index 00000000000..f5c498cc8ef
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro39.rs
@@ -0,0 +1,5 @@
+macro_rules! m {
+    ($e:expr (, parenthesis_forbidden)) => {{}}; // { dg-error "token .\\(. at start of matcher is not allowed after .expr. fragment" }
+                                                 // { dg-error "required first macro rule" "" { target *-*-* } .-1 }
+                                                 // { dg-error "failed to parse item in crate" "" { target *-*-* } .-2 }
+}
diff --git a/gcc/testsuite/rust/compile/macro4.rs b/gcc/testsuite/rust/compile/macro4.rs
new file mode 100644
index 00000000000..47ff6c93d87
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro4.rs
@@ -0,0 +1,3 @@
+macro_rules! one_keyword {
+    (kw) => {};
+}
diff --git a/gcc/testsuite/rust/compile/macro40.rs b/gcc/testsuite/rust/compile/macro40.rs
new file mode 100644
index 00000000000..7151f3a83bc
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro40.rs
@@ -0,0 +1,48 @@
+// { dg-additional-options "-w" }
+
+macro_rules! t {
+    () => {
+        i32
+    };
+}
+
+macro_rules! s {
+    () => {
+        *const i8
+    };
+}
+
+extern "C" {
+    fn printf(s: s!(), ...);
+}
+
+fn square(arg: t!()) -> t!() {
+    let input: t!() = arg;
+
+    input * input
+}
+
+trait Trait {
+    fn f() -> t!();
+    fn g(arg: t!());
+}
+
+struct Wrapper {
+    inner: t!(),
+}
+
+impl Trait for Wrapper {
+    fn f() -> t!() {
+        1
+    }
+
+    fn g(arg: t!()) {}
+}
+
+fn id<T>(arg: T) -> T {
+    arg
+}
+
+fn main() {
+    id::<t!()>(15);
+}
diff --git a/gcc/testsuite/rust/compile/macro41.rs b/gcc/testsuite/rust/compile/macro41.rs
new file mode 100644
index 00000000000..38244222924
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro41.rs
@@ -0,0 +1,13 @@
+macro_rules! empty {
+    ($($t:tt)*) => {};
+}
+
+empty! {nothing}
+empty! {struct OuterItem;}
+empty! {}
+
+fn main() {
+    empty! {as statement};
+    empty! {any child item};
+    empty! {};
+}
diff --git a/gcc/testsuite/rust/compile/macro42.rs b/gcc/testsuite/rust/compile/macro42.rs
new file mode 100644
index 00000000000..52d150b82ba
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro42.rs
@@ -0,0 +1,32 @@
+// { dg-additional-options "-w -frust-cfg=A" }
+#[rustc_builtin_macro]
+macro_rules! cfg {
+    () => {{}};
+}
+
+fn main() -> i32 {
+    let mut res = 0;
+    if cfg!(A) {
+        res = 1;
+    }
+
+    if cfg!(A) {
+        res = 2;
+    } else {
+        res = 3;
+    }
+
+    if cfg!(A) {
+        res = 4;
+    } else if cfg!(A) {
+        res = 5;
+    }
+
+    let res = if cfg!(A) {
+        6
+    } else {
+        7
+    };
+
+    return res;
+}
diff --git a/gcc/testsuite/rust/compile/macro5.rs b/gcc/testsuite/rust/compile/macro5.rs
new file mode 100644
index 00000000000..a5d80952e28
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro5.rs
@@ -0,0 +1,3 @@
+macro_rules! rust_keyword {
+    (fn) => {};
+}
diff --git a/gcc/testsuite/rust/compile/macro6.rs b/gcc/testsuite/rust/compile/macro6.rs
new file mode 100644
index 00000000000..0ca35ba6888
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro6.rs
@@ -0,0 +1,11 @@
+macro_rules! zero_or_one {
+    ($($a:literal)?) => { // { dg-error "invalid amount of matches for macro invocation. Expected between 0 and 1, got 2" }
+        f();
+    }
+}
+
+fn main() {
+    zero_or_one!();
+    zero_or_one!(14);
+    zero_or_one!(125 12 "gcc"); // { dg-error "Failed to match any rule within macro" }
+}
diff --git a/gcc/testsuite/rust/compile/macro7.rs b/gcc/testsuite/rust/compile/macro7.rs
new file mode 100644
index 00000000000..abc48057c54
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro7.rs
@@ -0,0 +1,13 @@
+fn f() {}
+
+macro_rules! one_or_more {
+    ($($a:literal)+) => { // { dg-error "invalid amount of matches for macro invocation" }
+        f();
+    };
+}
+
+fn main() {
+    one_or_more!(1 1 1 1 1 1 1 1 1 1 1 "rust" 'c');
+    one_or_more!(1);
+    one_or_more!(); // { dg-error "Failed to match any rule within macro" }
+}
diff --git a/gcc/testsuite/rust/compile/macro8.rs b/gcc/testsuite/rust/compile/macro8.rs
new file mode 100644
index 00000000000..d3e8af93a6e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro8.rs
@@ -0,0 +1,12 @@
+fn f() {}
+
+macro_rules! expr {
+    ($($a:expr)?) => {
+        f();
+    };
+}
+
+fn main() {
+    expr!();
+    expr!(14);
+}
diff --git a/gcc/testsuite/rust/compile/macro9.rs b/gcc/testsuite/rust/compile/macro9.rs
new file mode 100644
index 00000000000..9a59089b1e4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro9.rs
@@ -0,0 +1,17 @@
+macro_rules! add {
+    ($e:expr, $($es:expr),*) => {
+        $e + add!($($es),*)
+    };
+    ($e:expr) => {
+        $e
+    };
+}
+
+fn main() -> i32 {
+    let a = add!(15 2 9); // { dg-error "Failed to match any rule within macro" }
+    let b = add!(15);
+    let b = add!(15 14); // { dg-error "Failed to match any rule within macro" }
+    let b = add!(15, 14,); // { dg-error "Failed to match any rule within macro" }
+
+    0
+}
diff --git a/gcc/testsuite/rust/compile/macro_return.rs b/gcc/testsuite/rust/compile/macro_return.rs
new file mode 100644
index 00000000000..8b06f875cc0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro_return.rs
@@ -0,0 +1,10 @@
+// { dg-additional-options "-w" }
+
+macro_rules! add {
+    ($a:expr) => { $a };
+    ($a:expr, $($b:expr),+) => { $a + add!($($b),*) }
+}
+
+fn main() -> i32 {
+    add!(add!(1, 2))
+}
diff --git a/gcc/testsuite/rust/compile/match1.rs b/gcc/testsuite/rust/compile/match1.rs
new file mode 100644
index 00000000000..f649f3a1931
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match1.rs
@@ -0,0 +1,16 @@
+enum Foo {
+    A,
+    B,
+    C(char),
+    D { x: i64, y: i64 },
+}
+
+fn inspect(f: Foo) {
+    match f {
+        Foo::A => {}
+        Foo::B => {}
+        Foo::C(a, b) => {}
+        // { dg-error "this pattern has 2 fields but the corresponding tuple variant has 1 field" "" { target *-*-* } .-1 }
+        Foo::D { x, y } => {}
+    }
+}
diff --git a/gcc/testsuite/rust/compile/match2.rs b/gcc/testsuite/rust/compile/match2.rs
new file mode 100644
index 00000000000..359936a187c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match2.rs
@@ -0,0 +1,15 @@
+enum Foo {
+    A,
+    B,
+    C(char),
+    D { x: i64, y: i64 },
+}
+
+fn inspect(f: Foo) {
+    match f {
+        Foo::A => {}
+        Foo::B => {}
+        Foo::C(x) => {}
+        Foo::D { y } => {} // { dg-error "pattern does not mention fields x" }
+    }
+}
diff --git a/gcc/testsuite/rust/compile/match3.rs b/gcc/testsuite/rust/compile/match3.rs
new file mode 100644
index 00000000000..98181e85197
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match3.rs
@@ -0,0 +1,16 @@
+enum Foo {
+    A,
+    B,
+    C(char),
+    D { x: i64, y: i64 },
+}
+
+fn inspect(f: Foo) {
+    match f {
+        Foo::A => {}
+        Foo::B => {}
+        Foo::C(x) => {}
+        Foo::D { z } => {} // { dg-error "variant D does not have a field named z" }
+                           // { dg-error "pattern does not mention fields x, y" "" { target *-*-* } .-1 }
+    }
+}
diff --git a/gcc/testsuite/rust/compile/match4.rs b/gcc/testsuite/rust/compile/match4.rs
new file mode 100644
index 00000000000..35b90a64fa5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match4.rs
@@ -0,0 +1,16 @@
+enum Foo {
+    A,
+    B,
+    C(char),
+    D { x: i64, y: i64 },
+}
+
+fn inspect(f: Foo) {
+    match f {
+        Foo::A => {}
+        Foo::B => {}
+        Foo::C { a } => {}
+        // { dg-error "expected struct variant, found tuple variant C" "" { target *-*-* } .-1 }
+        Foo::D { x, y } => {}
+    }
+}
diff --git a/gcc/testsuite/rust/compile/match5.rs b/gcc/testsuite/rust/compile/match5.rs
new file mode 100644
index 00000000000..a5f934d6aeb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match5.rs
@@ -0,0 +1,15 @@
+enum Foo {
+    A,
+    B,
+    C(char),
+    D { x: i64, y: i64 },
+}
+
+fn inspect(f: Foo) {
+    match f {
+        Foo::A => {}
+        Foo::B => {}
+        Foo::C(a) => {}
+        Foo::D(x, y) => {} // { dg-error "expected tuple struct or tuple variant, found struct variant 'Foo::D'" }
+    }
+}
diff --git a/gcc/testsuite/rust/compile/match6.rs b/gcc/testsuite/rust/compile/match6.rs
new file mode 100644
index 00000000000..8fe06f7c116
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match6.rs
@@ -0,0 +1,18 @@
+fn foo() -> bool {
+    true
+}
+
+fn int32() -> i32 {
+    1
+}
+
+fn bar() -> i32 {
+    match foo() {
+        true => int32(),
+        false => 0
+    }
+}
+
+fn main() -> () {
+    bar();
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/match7.rs b/gcc/testsuite/rust/compile/match7.rs
new file mode 100644
index 00000000000..b16a1883522
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match7.rs
@@ -0,0 +1,12 @@
+fn bar (x: u8, y: u8) -> i32 {
+    match (x, y) {
+        (1, 1) => { return 1; }
+        (1, _) => { return -1; }
+    }
+
+    return 0;
+}
+
+fn main () -> () {
+    bar (1, 2);
+}
diff --git a/gcc/testsuite/rust/compile/method1.rs b/gcc/testsuite/rust/compile/method1.rs
new file mode 100644
index 00000000000..18652406085
--- /dev/null
+++ b/gcc/testsuite/rust/compile/method1.rs
@@ -0,0 +1,13 @@
+struct Foo(i32);
+impl Foo {
+    fn test() {}
+}
+
+pub fn main() {
+    let a;
+    a = Foo(123);
+
+    a.test();
+    // { dg-error "failed to resolve method for .test." "" { target *-*-* } .-1 }
+    // { dg-error {failed to type resolve expression} "" { target *-*-* } .-2 }
+}
diff --git a/gcc/testsuite/rust/compile/method2.rs b/gcc/testsuite/rust/compile/method2.rs
new file mode 100644
index 00000000000..c8699f77c6a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/method2.rs
@@ -0,0 +1,16 @@
+struct Foo<A, B>(A, B);
+
+impl Foo<i32, f32> {
+    fn test<X>(self, a: X) -> X {
+        a
+    }
+}
+
+fn main() {
+    let a;
+    a = Foo(123, 456f32);
+
+    let b;
+    b = a.test::<asfasfr>(false);
+    // { dg-error "failed to resolve TypePath: asfasfr" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/mismatch-crate-name.rs b/gcc/testsuite/rust/compile/mismatch-crate-name.rs
new file mode 100644
index 00000000000..e259b9e46cc
--- /dev/null
+++ b/gcc/testsuite/rust/compile/mismatch-crate-name.rs
@@ -0,0 +1,4 @@
+// { dg-additional-options "-frust-crate=another_name" }
+#![crate_name = "legit_name"]
+// { dg-error ".-frust-crate-name. and .#.crate_name.. are required to match, but .another_name. does not match .legit_name." "" { target *-*-* } .-1 }
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/missing_middle/both_path.rs b/gcc/testsuite/rust/compile/missing_middle/both_path.rs
new file mode 100644
index 00000000000..5e5ad15457a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/missing_middle/both_path.rs
@@ -0,0 +1,3 @@
+pub fn f() -> u32 {
+    5
+}
diff --git a/gcc/testsuite/rust/compile/missing_middle/explicit.not.rs b/gcc/testsuite/rust/compile/missing_middle/explicit.not.rs
new file mode 100644
index 00000000000..e28288b0f99
--- /dev/null
+++ b/gcc/testsuite/rust/compile/missing_middle/explicit.not.rs
@@ -0,0 +1 @@
+mod other;
diff --git a/gcc/testsuite/rust/compile/missing_middle/inner_path.rs b/gcc/testsuite/rust/compile/missing_middle/inner_path.rs
new file mode 100644
index 00000000000..daf4e3cc25a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/missing_middle/inner_path.rs
@@ -0,0 +1,3 @@
+pub fn f() -> u32 {
+    4
+}
diff --git a/gcc/testsuite/rust/compile/missing_middle/other.rs b/gcc/testsuite/rust/compile/missing_middle/other.rs
new file mode 100644
index 00000000000..0c0884ec968
--- /dev/null
+++ b/gcc/testsuite/rust/compile/missing_middle/other.rs
@@ -0,0 +1,3 @@
+pub fn f() -> u32 {
+    2
+}
diff --git a/gcc/testsuite/rust/compile/missing_middle/outer_path.rs b/gcc/testsuite/rust/compile/missing_middle/outer_path.rs
new file mode 100644
index 00000000000..fbe5074191b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/missing_middle/outer_path.rs
@@ -0,0 +1,3 @@
+pub fn f() -> u32 {
+    3
+}
diff --git a/gcc/testsuite/rust/compile/missing_middle/sub/mod.rs b/gcc/testsuite/rust/compile/missing_middle/sub/mod.rs
new file mode 100644
index 00000000000..f099d61e04a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/missing_middle/sub/mod.rs
@@ -0,0 +1,3 @@
+pub fn f() -> u32 {
+    1
+}
diff --git a/gcc/testsuite/rust/compile/missing_return1.rs b/gcc/testsuite/rust/compile/missing_return1.rs
new file mode 100644
index 00000000000..00bf393dbb9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/missing_return1.rs
@@ -0,0 +1,6 @@
+// { dg-error "expected .* got .*" "" { target *-*-* } 0 }
+fn test1() -> i32 {}
+
+fn main() {
+    let call1 = test1();
+}
diff --git a/gcc/testsuite/rust/compile/mod_missing_middle.rs b/gcc/testsuite/rust/compile/mod_missing_middle.rs
new file mode 100644
index 00000000000..79633407671
--- /dev/null
+++ b/gcc/testsuite/rust/compile/mod_missing_middle.rs
@@ -0,0 +1,29 @@
+// { dg-additional-options "-w" }
+
+mod missing_middle {
+    mod sub;
+
+    #[path = "explicit.not.rs"]
+    mod explicit;
+}
+
+#[path = "missing_middle"]
+mod with_outer_path_attr {
+    #[path = "outer_path.rs"]
+    mod inner;
+}
+
+mod with_inner_path_attr {
+    #![path = "missing_middle"]
+
+    #[path = "inner_path.rs"]
+    mod inner;
+}
+
+#[path = "missing_middle"]
+mod with_both_path_attr {
+    #![path = "this_is_ignored"]
+
+    #[path = "both_path.rs"]
+    mod inner;
+}
diff --git a/gcc/testsuite/rust/compile/never_type_err1.rs b/gcc/testsuite/rust/compile/never_type_err1.rs
new file mode 100644
index 00000000000..52b1283fadf
--- /dev/null
+++ b/gcc/testsuite/rust/compile/never_type_err1.rs
@@ -0,0 +1,14 @@
+fn test() {
+    let a;
+
+    // FIXME: Unimplemented features
+    a = if true { // { dg-error "expected .T.. got .!." }
+        return;
+    } else {
+        return;
+    };
+}
+
+fn main() {
+    test();
+}
diff --git a/gcc/testsuite/rust/compile/privacy1.rs b/gcc/testsuite/rust/compile/privacy1.rs
new file mode 100644
index 00000000000..1cc83c04abe
--- /dev/null
+++ b/gcc/testsuite/rust/compile/privacy1.rs
@@ -0,0 +1,11 @@
+mod orange {
+    mod green {
+        fn sain() {}
+        pub fn doux() {}
+    }
+
+    fn brown() {
+        green::sain(); // { dg-error "definition is private in this context" }
+        green::doux();
+    }
+}
diff --git a/gcc/testsuite/rust/compile/privacy2.rs b/gcc/testsuite/rust/compile/privacy2.rs
new file mode 100644
index 00000000000..3c0744928b1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/privacy2.rs
@@ -0,0 +1,13 @@
+// { dg-additional-options "-w" }
+
+mod orange {
+    fn tangerine() {}
+
+    mod green {
+        mod blue {
+            fn berry() {
+                tangerine();
+            }
+        }
+    }
+}
diff --git a/gcc/testsuite/rust/compile/privacy3.rs b/gcc/testsuite/rust/compile/privacy3.rs
new file mode 100644
index 00000000000..d48acea4786
--- /dev/null
+++ b/gcc/testsuite/rust/compile/privacy3.rs
@@ -0,0 +1,28 @@
+mod orange {
+    mod green {
+        fn sain_void() {}
+        fn sain() -> bool {
+            false
+        }
+        pub fn doux() {}
+    }
+
+    fn brown() {
+        if green::sain() {
+            // { dg-error "definition is private in this context" "" { target *-*-* } .-1 }
+            green::doux();
+        }
+
+        {
+            green::sain();
+            // { dg-error "definition is private in this context" "" { target *-*-* } .-1 }
+            green::sain();
+            // { dg-error "definition is private in this context" "" { target *-*-* } .-1 }
+            green::sain_void()
+            // { dg-error "definition is private in this context" "" { target *-*-* } .-1 }
+        }
+
+        let a = green::sain();
+        // { dg-error "definition is private in this context" "" { target *-*-* } .-1 }
+    }
+}
diff --git a/gcc/testsuite/rust/compile/privacy4.rs b/gcc/testsuite/rust/compile/privacy4.rs
new file mode 100644
index 00000000000..d1ce0afd654
--- /dev/null
+++ b/gcc/testsuite/rust/compile/privacy4.rs
@@ -0,0 +1,19 @@
+mod orange {
+    mod green {
+        fn bean<T>(value: T) -> T {
+            value
+        }
+    }
+
+    fn brown() {
+        green::bean::<bool>(false);
+        // { dg-error "definition is private in this context" "" { target *-*-* } .-1 }
+        let a = green::bean::<i32>(15);
+        // { dg-error "definition is private in this context" "" { target *-*-* } .-1 }
+
+        struct S;
+
+        let s = green::bean(S);
+        // { dg-error "definition is private in this context" "" { target *-*-* } .-1 }
+    }
+}
diff --git a/gcc/testsuite/rust/compile/privacy5.rs b/gcc/testsuite/rust/compile/privacy5.rs
new file mode 100644
index 00000000000..0e0e496dde2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/privacy5.rs
@@ -0,0 +1,17 @@
+mod orange {
+    mod green {
+        struct Foo;
+        pub(in orange) struct Bar;
+        pub struct Baz;
+    }
+
+    fn brown() {
+        let _ = green::Foo; // { dg-error "definition is private in this context" }
+        let _ = green::Bar;
+        let _ = green::Baz;
+
+        let _: green::Foo; // { dg-error "definition is private in this context" }
+
+        fn any(a0: green::Foo, a1: green::Bar) {} // { dg-error "20:definition is private in this context" }
+    }
+}
diff --git a/gcc/testsuite/rust/compile/privacy6.rs b/gcc/testsuite/rust/compile/privacy6.rs
new file mode 100644
index 00000000000..487ed024209
--- /dev/null
+++ b/gcc/testsuite/rust/compile/privacy6.rs
@@ -0,0 +1,39 @@
+// { dg-additional-options "-w" }
+
+struct Adt;
+enum EAdt {
+    V0,
+    V1,
+}
+struct Registers {
+    r0: i64,
+    r1: i64,
+    r2: i64,
+    r3: i64,
+}
+trait Foo {}
+
+fn foo1(value: bool) {}
+fn foo2(value: char) {}
+fn foo3(value: i32) {}
+fn foo4(value: u16) {}
+fn foo5(value: f64) {}
+fn foo6(value: usize) {}
+fn foo7(value: isize) {}
+fn foo8(value: Adt) {}
+fn foo9(value: EAdt) {}
+fn foo10(value: &str) {}
+fn foo11(value: *const i8) {}
+fn foo12<T>(value: T) {}
+fn foo13(value: [i32; 5]) {}
+fn foo14(value: [Adt]) {}
+fn foo15(value: fn(i32) -> i32) {}
+fn foo16(value: (i32, Adt)) {}
+fn foo17(value: (i32, [f64; 5])) {}
+fn foo18(value: Registers) {}
+fn foo19(value: &dyn Foo) {}
+fn foo20(value: &[Adt]) {}
+// FIXME: Uncomment once #1257 is fixed
+// fn foo21(value: fn(i32)) {}
+// fn foo22(value: fn()) {}
+fn foo23(value: fn() -> i32) {}
diff --git a/gcc/testsuite/rust/compile/pub_restricted_1.rs b/gcc/testsuite/rust/compile/pub_restricted_1.rs
new file mode 100644
index 00000000000..9bda9682403
--- /dev/null
+++ b/gcc/testsuite/rust/compile/pub_restricted_1.rs
@@ -0,0 +1,13 @@
+pub mod foo {
+    pub mod bar {
+        pub fn baz() {}
+
+        pub(in foo::bar) struct A0;
+    }
+}
+
+pub(in foo::fah::baz) struct A1; // { dg-error "cannot find simple path segment .fah." }
+pub(in fro::bulator::saindoux) struct A2; // { dg-error "cannot find simple path segment .fro." }
+pub(in foo::bar::saindoux) struct A3; // { dg-error "cannot find simple path segment .saindoux." }
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/pub_restricted_2.rs b/gcc/testsuite/rust/compile/pub_restricted_2.rs
new file mode 100644
index 00000000000..8588f2775ca
--- /dev/null
+++ b/gcc/testsuite/rust/compile/pub_restricted_2.rs
@@ -0,0 +1,18 @@
+// { dg-additional-options "-w" }
+
+mod foo {
+    mod bar {
+        mod baz {
+            pub(in baz) struct A0;
+            pub(in bar::baz) struct A1;
+            pub(in foo::bar::baz) struct A2;
+
+            mod sain {
+                mod doux {}
+            }
+
+            pub(in sain) struct A3; // { dg-error "restricted path is not an ancestor of the current module" }
+            pub(in sain::doux) struct A4; // { dg-error "restricted path is not an ancestor of the current module" }
+        }
+    }
+}
diff --git a/gcc/testsuite/rust/compile/pub_restricted_3.rs b/gcc/testsuite/rust/compile/pub_restricted_3.rs
new file mode 100644
index 00000000000..d477385d761
--- /dev/null
+++ b/gcc/testsuite/rust/compile/pub_restricted_3.rs
@@ -0,0 +1,11 @@
+// { dg-additional-options "-w" }
+
+mod foo {
+    mod bar {
+        pub(in foo) fn baz() {}
+    }
+
+    fn baz() {
+        bar::baz(); // no error, foo::bar::baz is public in foo
+    }
+}
diff --git a/gcc/testsuite/rust/compile/raw_identifiers_bad_keywords.rs b/gcc/testsuite/rust/compile/raw_identifiers_bad_keywords.rs
new file mode 100644
index 00000000000..854d7e6edee
--- /dev/null
+++ b/gcc/testsuite/rust/compile/raw_identifiers_bad_keywords.rs
@@ -0,0 +1,3 @@
+pub fn plus(n: i32, m: i32) -> i32 {
+    r#crate /* { dg-error "forbidden raw identifier" } */
+}
diff --git a/gcc/testsuite/rust/compile/raw_identifiers_underscore.rs b/gcc/testsuite/rust/compile/raw_identifiers_underscore.rs
new file mode 100644
index 00000000000..86e9013a50b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/raw_identifiers_underscore.rs
@@ -0,0 +1,3 @@
+pub fn s(num: i32) -> i32 {
+    r#_ * num /* { dg-error "not a valid raw identifier" } */
+}
diff --git a/gcc/testsuite/rust/compile/rawbytestring.rs b/gcc/testsuite/rust/compile/rawbytestring.rs
new file mode 100644
index 0000000000000000000000000000000000000000..9c6b762a7fd378206a3bfe21db5b708890f5466f
GIT binary patch
diff --git a/gcc/testsuite/rust/compile/redef_error1.rs b/gcc/testsuite/rust/compile/redef_error1.rs
new file mode 100644
index 00000000000..ae51e36c87f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/redef_error1.rs
@@ -0,0 +1,8 @@
+struct S1 {
+    x: f64,
+    y: f64,
+}
+
+struct S1(i32, bool); // { dg-error "redefined multiple times" }
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/redef_error2.rs b/gcc/testsuite/rust/compile/redef_error2.rs
new file mode 100644
index 00000000000..65793bcda8a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/redef_error2.rs
@@ -0,0 +1,4 @@
+const TEST: i32 = 2;
+const TEST: f32 = 3.0; // { dg-error "redefined multiple times" }
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/redef_error3.rs b/gcc/testsuite/rust/compile/redef_error3.rs
new file mode 100644
index 00000000000..a4bf1ed3d8c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/redef_error3.rs
@@ -0,0 +1,9 @@
+fn test() -> bool {
+    true
+}
+
+fn test() -> i32 { // { dg-error "redefined multiple times" }
+    123
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/redef_error4.rs b/gcc/testsuite/rust/compile/redef_error4.rs
new file mode 100644
index 00000000000..a250c0ac00e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/redef_error4.rs
@@ -0,0 +1,27 @@
+struct Foo(i32, bool);
+
+impl Foo {
+    fn new(a: i32, b: bool) -> Foo {
+        Foo(a, b)
+    }
+
+    fn test() -> i32 {
+        test()
+    }
+
+    fn test() -> bool { // { dg-error "redefined multiple times" }
+        true
+    }
+}
+
+fn test() -> i32 {
+    123
+}
+
+fn main() {
+    let a;
+    a = Foo::new(1, true);
+
+    let b;
+    b = Foo::test();
+}
diff --git a/gcc/testsuite/rust/compile/redef_error5.rs b/gcc/testsuite/rust/compile/redef_error5.rs
new file mode 100644
index 00000000000..dc6ad50e104
--- /dev/null
+++ b/gcc/testsuite/rust/compile/redef_error5.rs
@@ -0,0 +1,8 @@
+struct Foo(i32, bool);
+
+impl Foo {
+    const TEST: i32 = 123;
+    const TEST: bool = false; // { dg-error "redefined multiple times"  }
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/redef_error6.rs b/gcc/testsuite/rust/compile/redef_error6.rs
new file mode 100644
index 00000000000..664c6ae9894
--- /dev/null
+++ b/gcc/testsuite/rust/compile/redef_error6.rs
@@ -0,0 +1,13 @@
+struct Foo<T>(T, usize);
+
+impl Foo<i32> {
+    fn test() -> i32 {
+        123
+    }
+
+    fn test(self) -> i32 { // { dg-error "redefined multiple times" }
+        self.0
+    }
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/reference1.rs b/gcc/testsuite/rust/compile/reference1.rs
new file mode 100644
index 00000000000..ff791533754
--- /dev/null
+++ b/gcc/testsuite/rust/compile/reference1.rs
@@ -0,0 +1,6 @@
+fn main() {
+    let a = &123;
+    let b: &mut i32 = a;
+    // { dg-error "mismatched mutability" "" { target *-*-* } .-1 }
+    // { dg-error "expected .&mut i32. got .& i32." "" { target *-*-* } .-2 }
+}
diff --git a/gcc/testsuite/rust/compile/self-path1.rs b/gcc/testsuite/rust/compile/self-path1.rs
new file mode 100644
index 00000000000..425ba848fc0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/self-path1.rs
@@ -0,0 +1,12 @@
+// { dg-additional-options "-w" }
+struct foo;
+
+fn bar() -> self::foo {
+    crate::foo
+}
+
+fn baz() {
+    let a: foo = self::bar();
+
+    crate::bar();
+}
diff --git a/gcc/testsuite/rust/compile/self-path2.rs b/gcc/testsuite/rust/compile/self-path2.rs
new file mode 100644
index 00000000000..b9b82cae5a6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/self-path2.rs
@@ -0,0 +1,21 @@
+// { dg-additional-options "-w" }
+struct foo;
+
+fn bar() -> self::foo {
+    crate::foo
+}
+
+fn baz() {
+    let a: foo = self::bar();
+
+    crate::bar();
+
+    crate::self::foo();
+    // { dg-error "failed to resolve: .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 }
diff --git a/gcc/testsuite/rust/compile/shadow1.rs b/gcc/testsuite/rust/compile/shadow1.rs
new file mode 100644
index 00000000000..77410e932da
--- /dev/null
+++ b/gcc/testsuite/rust/compile/shadow1.rs
@@ -0,0 +1,7 @@
+fn main() {
+    let mut x = 5;
+    let mut x;
+    x = true;
+    x = x + 2; // { dg-error "cannot apply this operator to types bool and <integer>"  }
+               // { dg-error {failed to type resolve expression} "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/specify-crate-name.rs b/gcc/testsuite/rust/compile/specify-crate-name.rs
new file mode 100644
index 00000000000..a8679157024
--- /dev/null
+++ b/gcc/testsuite/rust/compile/specify-crate-name.rs
@@ -0,0 +1,7 @@
+// { dg-additional-options "-frust-crate=fancy_crate_name -fdump-tree-gimple" }
+pub fn does_nothing() {}
+fn main() {
+    does_nothing()
+}
+// { dg-final { scan-tree-dump-times {fancy_crate_name::does_nothing} 2 gimple } }
+// { dg-final { scan-tree-dump-times {fancy_crate_name::main} 1 gimple } }
diff --git a/gcc/testsuite/rust/compile/static_var1.rs b/gcc/testsuite/rust/compile/static_var1.rs
new file mode 100644
index 00000000000..b3b5751c932
--- /dev/null
+++ b/gcc/testsuite/rust/compile/static_var1.rs
@@ -0,0 +1,5 @@
+static x = 3; // { dg-error "expecting ':' but '=' found" }
+
+fn main() {// { dg-error "failed to parse item in crate" }
+    let y = x +1;
+}
diff --git a/gcc/testsuite/rust/compile/stmt_with_block_err1.rs b/gcc/testsuite/rust/compile/stmt_with_block_err1.rs
new file mode 100644
index 00000000000..8780d0feeac
--- /dev/null
+++ b/gcc/testsuite/rust/compile/stmt_with_block_err1.rs
@@ -0,0 +1,17 @@
+fn test(x: i32) -> i32 {
+    if x > 1 { // { dg-error "expected .... got .<integer>." }
+        1
+    } else {
+        2
+    }
+
+    { // { dg-error "expected .... got .<integer>." }
+        3
+    }
+
+    3
+}
+
+fn main() {
+    let a = test(0);
+}
diff --git a/gcc/testsuite/rust/compile/struct_align1.rs b/gcc/testsuite/rust/compile/struct_align1.rs
new file mode 100644
index 00000000000..22eb6bc80fb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/struct_align1.rs
@@ -0,0 +1,19 @@
+#[repr(align(8))]
+struct Foo {
+    x: i16,
+    // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+    y: i8,
+    // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+    z: i32,
+    // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+#[repr(align(8))]
+struct Bar(i8, i32);
+
+fn main () {
+    let f = Foo { x: 5, y: 2, z: 13 };
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let b = Bar (7, 262);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/struct_align2.rs b/gcc/testsuite/rust/compile/struct_align2.rs
new file mode 100644
index 00000000000..ac490643a36
--- /dev/null
+++ b/gcc/testsuite/rust/compile/struct_align2.rs
@@ -0,0 +1,18 @@
+
+fn main () {
+
+    #[repr(align(8))]
+    struct Baz {
+        x: u16,
+        y: u32,
+    };
+
+    #[repr(align(4))]
+    struct Qux (u8, i16);
+
+    let b = Baz { x: 5, y: 1984 };
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let c = Qux (1, 2);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/struct_init1.rs b/gcc/testsuite/rust/compile/struct_init1.rs
new file mode 100644
index 00000000000..1875fb4f33e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/struct_init1.rs
@@ -0,0 +1,10 @@
+struct Foo {
+    a: f32,
+    b: f32,
+}
+
+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" }
+}
diff --git a/gcc/testsuite/rust/compile/struct_pack1.rs b/gcc/testsuite/rust/compile/struct_pack1.rs
new file mode 100644
index 00000000000..eb9d879c1dc
--- /dev/null
+++ b/gcc/testsuite/rust/compile/struct_pack1.rs
@@ -0,0 +1,19 @@
+#[repr(packed(2))]
+struct Foo {
+    x: i16,
+    // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+    y: i8,
+    // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+    z: i32,
+    // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+#[repr(packed)]
+struct Bar(i8, i32);
+
+fn main () {
+    let f = Foo { x: 5, y: 2, z: 13 };
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let b = Bar (7, 262);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/struct_pack2.rs b/gcc/testsuite/rust/compile/struct_pack2.rs
new file mode 100644
index 00000000000..e5f74c20bb0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/struct_pack2.rs
@@ -0,0 +1,18 @@
+
+fn main () {
+
+    #[repr(packed(2))]
+    struct Baz {
+        x: u16,
+        y: u32,
+    };
+
+    #[repr(packed)]
+    struct Qux (u8, i16);
+
+    let b = Baz { x: 5, y: 1984 };
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let c = Qux (1, 2);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/syntax-only.rs b/gcc/testsuite/rust/compile/syntax-only.rs
new file mode 100644
index 00000000000..cd84907bf84
--- /dev/null
+++ b/gcc/testsuite/rust/compile/syntax-only.rs
@@ -0,0 +1,6 @@
+// { dg-additional-options "-fsyntax-only" }
+
+fn main() {
+    let mut a = 15;
+    a = true;
+}
diff --git a/gcc/testsuite/rust/compile/test_mod.rs b/gcc/testsuite/rust/compile/test_mod.rs
new file mode 100644
index 00000000000..4b3c000236b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/test_mod.rs
@@ -0,0 +1,6 @@
+//! test_mod inner doc comment
+//!
+//! foo bar baz cake pizza carbs
+
+pub struct Test(pub i32);
+// { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/torture/all_doc_comment_line_blocks.rs b/gcc/testsuite/rust/compile/torture/all_doc_comment_line_blocks.rs
new file mode 100644
index 00000000000..b7368ba29ee
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/all_doc_comment_line_blocks.rs
@@ -0,0 +1,45 @@
+// comment line not a doc
+/* comment block not a doc                   */
+
+//! inner line comment for most outer crate
+/*! inner block comment for most outer crate */
+
+// comment line not a doc
+/* comment block not a doc                   */
+
+/// outer doc line for module
+/** outer doc block for module               */
+pub mod module {
+    //!  inner line doc
+    //!! inner line doc!
+    /*!  inner block doc  */
+    /*!! inner block doc! */
+
+    //   line comment
+    ///  outer line doc
+    //// line comment
+
+    /*   block comment   */
+    /**  outer block doc */
+    /*** block comment   */
+
+    mod block_doc_comments {
+        /*   /* */  /** */  /*! */  */
+        /*!  /* */  /** */  /*! */  */
+        /**  /* */  /** */  /*! */  */
+        mod item {}
+    }
+
+    pub mod empty {
+        //!
+        /*!*/
+        //
+
+        ///
+        // the following warning is issued one line earlier
+        mod doc {}
+        /**/
+        /***/
+    }
+}
+pub fn main() {}
diff --git a/gcc/testsuite/rust/compile/torture/all_doc_comment_line_blocks_crlf.rs b/gcc/testsuite/rust/compile/torture/all_doc_comment_line_blocks_crlf.rs
new file mode 100644
index 00000000000..9f2f2207397
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/all_doc_comment_line_blocks_crlf.rs
@@ -0,0 +1,48 @@
+// comment line not a doc
+/* comment block not a doc                   */
+
+//! inner line comment for most outer crate
+/*! inner block comment for most outer crate */
+
+// comment line not a doc
+/* comment block not a doc                   */
+
+/// outer doc line for module
+/** outer doc block for module               */
+pub mod module
+{
+  //!  inner line doc
+  //!! inner line doc!
+  /*!  inner block doc  */
+  /*!! inner block doc! */
+
+  //   line comment
+  ///  outer line doc
+  //// line comment
+
+  /*   block comment   */
+  /**  outer block doc */
+  /*** block comment   */
+
+  mod block_doc_comments
+  {
+    /*   /* */  /** */  /*! */  */
+    /*!  /* */  /** */  /*! */  */
+    /**  /* */  /** */  /*! */  */
+    mod item { }
+  }
+
+  pub mod empty
+  {
+    //!
+    /*!*/
+    //
+
+    ///
+    mod doc { }
+
+    /**/
+    /***/
+  }
+}
+pub fn main () { }
diff --git a/gcc/testsuite/rust/compile/torture/arithmetic_expressions1.rs b/gcc/testsuite/rust/compile/torture/arithmetic_expressions1.rs
new file mode 100644
index 00000000000..4c3ee77c835
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/arithmetic_expressions1.rs
@@ -0,0 +1,30 @@
+// { dg-prune-output "warning: unused name" } as there are many of these expected.
+
+fn main() {
+    let a: i32 = 1;
+    let b: f32 = 5f32;
+    let c: bool = true;
+
+    let a1: i32 = a + 1;
+    let a2: i32 = a - 2;
+    let a3: i32 = a * 3;
+    let a4: i32 = a / 4;
+    let a5: i32 = a % 5;
+
+    let b1: f32 = b + 1f32;
+    let b2: f32 = b - 2f32;
+    let b3: f32 = b * 3f32;
+    let b4: f32 = b / 4f32;
+    // let b5: f32 = b % 5f32;
+
+    let aa1: i32 = a & 1;
+    let aa2: i32 = a | 2;
+    let aa2: i32 = a ^ 3;
+
+    let c1: bool = c & true;
+    let c2: bool = c | false;
+    let c3: bool = c ^ true;
+
+    let aaa1: i32 = a << 1;
+    let aaa2: i32 = a >> 2;
+}
diff --git a/gcc/testsuite/rust/compile/torture/array_const_fold_1.rs b/gcc/testsuite/rust/compile/torture/array_const_fold_1.rs
new file mode 100644
index 00000000000..e45c9389c93
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/array_const_fold_1.rs
@@ -0,0 +1,2 @@
+const TEST: [i32; 16] = [2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8];
+// { dg-warning "unused name" "" { target *-*-* } .-1 }
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/torture/array_const_fold_2.rs b/gcc/testsuite/rust/compile/torture/array_const_fold_2.rs
new file mode 100644
index 00000000000..b42a68e5ddb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/array_const_fold_2.rs
@@ -0,0 +1,3 @@
+const SIZE: usize = 14 + 2;
+const TEST: [i32; SIZE] = [2; SIZE];
+// { dg-warning "unused name" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/torture/array_function.rs b/gcc/testsuite/rust/compile/torture/array_function.rs
new file mode 100644
index 00000000000..4e2b2e03f31
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/array_function.rs
@@ -0,0 +1,8 @@
+fn foo() -> i32 {
+    1
+}
+
+
+fn main() {
+    let _a: [i32; 1] = [foo()];
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/torture/array_type_infer.rs b/gcc/testsuite/rust/compile/torture/array_type_infer.rs
new file mode 100644
index 00000000000..6f21bf2420c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/array_type_infer.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let arr: [_; 5] = [1, 2, 3, 4, 5];
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/array_zero_length.rs b/gcc/testsuite/rust/compile/torture/array_zero_length.rs
new file mode 100644
index 00000000000..3155b1c48c0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/array_zero_length.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let arr = ["Hello"; 0];
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/arrays1.rs b/gcc/testsuite/rust/compile/torture/arrays1.rs
new file mode 100644
index 00000000000..7250e0fa2af
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/arrays1.rs
@@ -0,0 +1,9 @@
+fn main() {
+    let xs: [i32; 5] = [1, 2, 3, 4, 5];
+    let xy = [6, 7, 8];
+
+    let a = xs[0];
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let b = xy[2];
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/arrays2.rs b/gcc/testsuite/rust/compile/torture/arrays2.rs
new file mode 100644
index 00000000000..55491f34524
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/arrays2.rs
@@ -0,0 +1,8 @@
+fn main() {
+    let mut array: [i32; 3] = [0; 3];
+
+    let a = array[0];
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let mut c;
+    c = array[2];
+}
diff --git a/gcc/testsuite/rust/compile/torture/arrays3.rs b/gcc/testsuite/rust/compile/torture/arrays3.rs
new file mode 100644
index 00000000000..372d969aa07
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/arrays3.rs
@@ -0,0 +1,6 @@
+const TEST: usize = 6;
+
+fn main() {
+    let a: [_; 12] = [123; TEST * 2];
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/arrays4.rs b/gcc/testsuite/rust/compile/torture/arrays4.rs
new file mode 100644
index 00000000000..ac317fedf44
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/arrays4.rs
@@ -0,0 +1,6 @@
+const TEST: usize = 4;
+
+fn main() {
+    let a: [_; TEST + 1 + 2] = [123; 7];
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/arrays5.rs b/gcc/testsuite/rust/compile/torture/arrays5.rs
new file mode 100644
index 00000000000..58950a17a15
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/arrays5.rs
@@ -0,0 +1,6 @@
+
+// Checks that we don't try to allocate a 4TB array during compilation
+fn main () {
+    let x = [0; 4 * 1024 * 1024 * 1024 * 1024];
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/arrays6.rs b/gcc/testsuite/rust/compile/torture/arrays6.rs
new file mode 100644
index 00000000000..c7212d3f183
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/arrays6.rs
@@ -0,0 +1,10 @@
+
+// Checks that we don't try to allocate a 4TB array during compilation
+fn foo() -> [u8; 4 * 1024 * 1024 * 1024 * 1024] {
+    [0; 4 * 1024 * 1024 * 1024 * 1024]
+}
+
+fn main () {
+    let x = foo ();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/arrays_index1.rs b/gcc/testsuite/rust/compile/torture/arrays_index1.rs
new file mode 100644
index 00000000000..1fe5de91bcf
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/arrays_index1.rs
@@ -0,0 +1,9 @@
+fn main() {
+    let mut array: [i32; 3] = [0; 3];
+
+    let a = array[0];
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let x = 0;
+    let mut c;
+    c = array[x+1];
+}
diff --git a/gcc/testsuite/rust/compile/torture/arrays_index2.rs b/gcc/testsuite/rust/compile/torture/arrays_index2.rs
new file mode 100644
index 00000000000..f9bee7748ee
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/arrays_index2.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let mut array: [i32; 3] = [0; 3];
+    array[0] = 1;
+}
diff --git a/gcc/testsuite/rust/compile/torture/arrays_index3.rs b/gcc/testsuite/rust/compile/torture/arrays_index3.rs
new file mode 100644
index 00000000000..8fa0a226d02
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/arrays_index3.rs
@@ -0,0 +1,15 @@
+fn foo() -> usize {
+    1
+}
+    
+fn bar() -> [i32; 1] {
+    [0]
+}
+    
+    
+        
+fn main() -> () {
+    let a = [10];
+    let _b = a[foo()];
+    let _c = bar()[foo()];
+}
diff --git a/gcc/testsuite/rust/compile/torture/as_bool_char.rs b/gcc/testsuite/rust/compile/torture/as_bool_char.rs
new file mode 100644
index 00000000000..d687499384a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/as_bool_char.rs
@@ -0,0 +1,36 @@
+extern "C" { fn abort (); }
+
+pub fn main ()
+{
+  let t = true;
+  let f = false;
+  let one = t as u8;
+  let zero = f as u8;
+
+  if one != 1 || zero != 0 { unsafe { abort (); } }
+
+  let isizeone = true as isize;
+  let usizezero = false as usize;
+
+  if isizeone != 1 || usizezero != 0 { unsafe { abort (); } }
+
+  let i32zero = f as i32;
+  let u128one = t as u128;
+
+  if u128one != 1 || i32zero != 0 { unsafe { abort (); } }
+
+  let a = 'a';
+  let b = 'b';
+  let ua = a as u8;
+  let ib = b as i32;
+
+  if (ua + 1) as i32 != ib { unsafe { abort (); } }
+
+  let tt = ua;
+  let aa = tt as char;
+
+  let ttt = tt + 1;
+  let ab = ttt as char;
+
+  if aa != 'a' || ab != 'b' { unsafe { abort (); } }
+}
diff --git a/gcc/testsuite/rust/compile/torture/associated_types1.rs b/gcc/testsuite/rust/compile/torture/associated_types1.rs
new file mode 100644
index 00000000000..bf181df7045
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/associated_types1.rs
@@ -0,0 +1,12 @@
+pub trait Foo {
+    type A;
+
+    fn boo(&self) -> <Self as Foo>::A;
+}
+
+fn foo2<I: Foo>(x: I) {
+    // { dg-warning "function is never used: .foo2." "" { target *-*-* } .-1 }
+    x.boo();
+}
+
+pub fn main() {}
diff --git a/gcc/testsuite/rust/compile/torture/autoderef1.rs b/gcc/testsuite/rust/compile/torture/autoderef1.rs
new file mode 100644
index 00000000000..0cf070f1f37
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/autoderef1.rs
@@ -0,0 +1,15 @@
+struct Foo(i32, bool);
+struct Bar {
+    a: i32,
+    b: bool,
+}
+
+fn main() {
+    let a = &Foo(123, false);
+    let _b: i32 = a.0;
+    let _c: bool = a.1;
+
+    let a = &Bar { a: 456, b: false };
+    let _b: i32 = a.a;
+    let _c: bool = a.b;
+}
diff --git a/gcc/testsuite/rust/compile/torture/block_expr1.rs b/gcc/testsuite/rust/compile/torture/block_expr1.rs
new file mode 100644
index 00000000000..011cc1fc89d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/block_expr1.rs
@@ -0,0 +1,29 @@
+fn test3(x: i32) -> i32 {
+    if x > 1 {
+        5
+    } else {
+        0
+    }
+}
+
+fn test5(x: i32) -> i32 {
+    if x > 1 {
+        if x == 5 {
+            7
+        } else {
+            9
+        }
+    } else {
+        0
+    }
+}
+
+fn main() {
+    let call3: i32 = { test3(3) + 2 };
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let call5 = {
+        // { dg-warning "unused name" "" { target *-*-* } .-1 }
+        let a = test5(5);
+        a + 1
+    };
+}
diff --git a/gcc/testsuite/rust/compile/torture/block_expr2.rs b/gcc/testsuite/rust/compile/torture/block_expr2.rs
new file mode 100644
index 00000000000..7c3ff698097
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/block_expr2.rs
@@ -0,0 +1,15 @@
+fn test() -> i32 {
+    123
+}
+
+fn main() {
+    let a = { test() };
+    let b = {
+        // { dg-warning "unused name" "" { target *-*-* } .-1 }
+        if a > 10 {
+            a - 1
+        } else {
+            a + 1
+        }
+    };
+}
diff --git a/gcc/testsuite/rust/compile/torture/block_expr3.rs b/gcc/testsuite/rust/compile/torture/block_expr3.rs
new file mode 100644
index 00000000000..6914b6379d7
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/block_expr3.rs
@@ -0,0 +1,14 @@
+fn main() {
+    let x = 111;
+
+    let a = {
+        // { dg-warning "unused name" "" { target *-*-* } .-1 }
+        if x == 10 {
+            123
+        } else if x < 10 {
+            456
+        } else {
+            789
+        }
+    };
+}
diff --git a/gcc/testsuite/rust/compile/torture/block_expr4.rs b/gcc/testsuite/rust/compile/torture/block_expr4.rs
new file mode 100644
index 00000000000..da033ef9ef4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/block_expr4.rs
@@ -0,0 +1,8 @@
+fn foo() -> isize {
+    0
+}
+
+fn main() {
+    let a = foo();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/block_expr5.rs b/gcc/testsuite/rust/compile/torture/block_expr5.rs
new file mode 100644
index 00000000000..7e164a949bb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/block_expr5.rs
@@ -0,0 +1,40 @@
+fn foo() -> i32 {
+    0
+}
+
+fn bar() -> i32 {
+    foo();
+    foo()
+}
+
+fn baz() -> i32 {
+    {
+        bar();
+        bar();
+    }
+    {
+        bar();
+        bar()
+    };
+    {
+        bar();
+        bar()
+    }
+}
+
+fn test(ok: i32) -> i32 {
+    if ok >= 1 {
+        foo()
+    } else if ok <= -1 {
+        bar()
+    } else {
+        baz()
+    }
+}
+
+fn main() {
+    let a = foo();
+    let b = bar();
+    let c = baz();
+    test(a + b + c);
+}
diff --git a/gcc/testsuite/rust/compile/torture/block_expr_parser_bug.rs b/gcc/testsuite/rust/compile/torture/block_expr_parser_bug.rs
new file mode 100644
index 00000000000..468aace9881
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/block_expr_parser_bug.rs
@@ -0,0 +1,5 @@
+fn main() {
+    let a = 123;
+    let b = if a > 10 { a - 1 } else { a + 1 };
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/bom.rs b/gcc/testsuite/rust/compile/torture/bom.rs
new file mode 100644
index 00000000000..5edcab227ee
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/bom.rs
@@ -0,0 +1 @@
+﻿pub fn main () { }
diff --git a/gcc/testsuite/rust/compile/torture/bom_comment.rs b/gcc/testsuite/rust/compile/torture/bom_comment.rs
new file mode 100644
index 00000000000..020e1707b55
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/bom_comment.rs
@@ -0,0 +1,2 @@
+﻿// UTF8 BOM
+pub fn main () { }
diff --git a/gcc/testsuite/rust/compile/torture/bom_shebang.rs b/gcc/testsuite/rust/compile/torture/bom_shebang.rs
new file mode 100644
index 00000000000..4c552e8d71d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/bom_shebang.rs
@@ -0,0 +1,2 @@
+﻿#!/usr/bin/cat
+pub fn main () { }
diff --git a/gcc/testsuite/rust/compile/torture/bom_whitespace.rs b/gcc/testsuite/rust/compile/torture/bom_whitespace.rs
new file mode 100644
index 00000000000..b10d5654473
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/bom_whitespace.rs
@@ -0,0 +1,2 @@
+﻿
+pub fn main () { }
diff --git a/gcc/testsuite/rust/compile/torture/bools_eq.rs b/gcc/testsuite/rust/compile/torture/bools_eq.rs
new file mode 100644
index 00000000000..965127b5d54
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/bools_eq.rs
@@ -0,0 +1,18 @@
+extern "C"
+{
+  fn abort ();
+}
+
+fn beq (a: bool, b: bool) -> bool
+{
+  let bools_eq = a == b;
+  bools_eq
+}
+
+pub fn main ()
+{
+  let a = true;
+  let b = false;
+  let r = beq (a, b);
+  if r { unsafe { abort (); } }
+}
diff --git a/gcc/testsuite/rust/compile/torture/borrow1.rs b/gcc/testsuite/rust/compile/torture/borrow1.rs
new file mode 100644
index 00000000000..8afa4746fef
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/borrow1.rs
@@ -0,0 +1,17 @@
+fn main() {
+    let a: i32;
+    a = 123;
+
+    let b: &i32;
+    b = &a;
+
+    let aa;
+    aa = 456;
+    let bb: &_;
+    bb = &a;
+
+    let aaa;
+    aaa = 123;
+    let bbb;
+    bbb = &aaa;
+}
diff --git a/gcc/testsuite/rust/compile/torture/borrow_function.rs b/gcc/testsuite/rust/compile/torture/borrow_function.rs
new file mode 100644
index 00000000000..98c6f99683e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/borrow_function.rs
@@ -0,0 +1,5 @@
+fn foo() {}
+
+fn main() {
+    let _a = &foo;
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/torture/break_function.rs b/gcc/testsuite/rust/compile/torture/break_function.rs
new file mode 100644
index 00000000000..043e91c9502
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/break_function.rs
@@ -0,0 +1,10 @@
+fn foo() -> i32 {
+    1
+}
+    
+fn main() {
+    let _a = loop {
+        break foo();
+    };
+}
+    
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/torture/byte_char_str.rs b/gcc/testsuite/rust/compile/torture/byte_char_str.rs
new file mode 100644
index 00000000000..bc3ec5014e8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/byte_char_str.rs
@@ -0,0 +1,8 @@
+pub fn main ()
+{
+  let _c = 'x';
+  let _bc = b'x';
+
+  let _s = "abc";
+  let _bs = b"abc";
+}
diff --git a/gcc/testsuite/rust/compile/torture/byte_str.rs b/gcc/testsuite/rust/compile/torture/byte_str.rs
new file mode 100644
index 00000000000..28934d2581d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/byte_str.rs
@@ -0,0 +1,4 @@
+pub fn main() {
+    let a: &[u8; 4];
+    a = b"test";
+}
diff --git a/gcc/testsuite/rust/compile/torture/cast1.rs b/gcc/testsuite/rust/compile/torture/cast1.rs
new file mode 100644
index 00000000000..845d08cea01
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/cast1.rs
@@ -0,0 +1,5 @@
+fn main() {
+    let a: *const i32 = &123;
+    let b: *mut i32 = (a as *mut i32);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/cast2.rs b/gcc/testsuite/rust/compile/torture/cast2.rs
new file mode 100644
index 00000000000..82925e93271
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/cast2.rs
@@ -0,0 +1,5 @@
+fn main() {
+    let a: i32 = 123i32;
+    let b: u8 = a as u8;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/cast3.rs b/gcc/testsuite/rust/compile/torture/cast3.rs
new file mode 100644
index 00000000000..1de95687039
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/cast3.rs
@@ -0,0 +1,6 @@
+fn main() {
+    let a = "foo\0";
+    let b = a as *const str;
+    let c = b as *const i8;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/cfg_attr.rs b/gcc/testsuite/rust/compile/torture/cfg_attr.rs
new file mode 100644
index 00000000000..d65faf2972a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/cfg_attr.rs
@@ -0,0 +1,7 @@
+mod fake {} // Add one line so gccrs doesn't believe we're parsing a shebang
+
+#[cfg_attr(feature = "somefeature", attribute = "someattr")]
+struct Feature;
+// { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/torture/char1.rs b/gcc/testsuite/rust/compile/torture/char1.rs
new file mode 100644
index 00000000000..73835c218a2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/char1.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let a;
+    a = 'c';
+}
diff --git a/gcc/testsuite/rust/compile/torture/check-doc-attr-string.rs b/gcc/testsuite/rust/compile/torture/check-doc-attr-string.rs
new file mode 100644
index 00000000000..e113120bdbc
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/check-doc-attr-string.rs
@@ -0,0 +1,18 @@
+#![crate_type = "lib"]
+
+#[doc(alias = "foo")] // ok!
+#[doc(alias("bar", "baz"))] // ok!
+pub struct Bar;
+
+#[doc(alias = "
+")] // { dg-error "invalid character used" "" { target *-*-* } .-1 }
+pub struct Foo;
+
+#[doc(alias(
+    "
+"
+))] // ko but unchecked for now
+pub struct Foo2;
+
+#[doc(whatever = "buidule")] // ko as well but unchecked for now
+struct Boo;
diff --git a/gcc/testsuite/rust/compile/torture/coercion1.rs b/gcc/testsuite/rust/compile/torture/coercion1.rs
new file mode 100644
index 00000000000..3bfa938ffdc
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/coercion1.rs
@@ -0,0 +1,11 @@
+pub fn main() {
+    let a: &i32 = &123;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let b: &mut i32 = &mut 123;
+
+    let c: &i32 = &mut 123;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let d: &i32 = b;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/coercion2.rs b/gcc/testsuite/rust/compile/torture/coercion2.rs
new file mode 100644
index 00000000000..127f257f8b6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/coercion2.rs
@@ -0,0 +1,20 @@
+pub fn main() {
+    let a: *const i32 = &123;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let b: &i32 = &123;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let c: &mut i32 = &mut 123;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let d: *mut i32 = &mut 123;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let e: &i32 = &mut 123;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let f: *const i32 = &mut 123;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let g = &123;
+    let h: *const i32 = g;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/comparison_expr1.rs b/gcc/testsuite/rust/compile/torture/comparison_expr1.rs
new file mode 100644
index 00000000000..ed71ec89025
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/comparison_expr1.rs
@@ -0,0 +1,38 @@
+fn is_zero(x: i32) -> bool {
+    x == 0
+}
+
+fn is_not_zero(x: i32) -> bool {
+    x != 0
+}
+
+fn is_positive(x: i32) -> bool {
+    x > 0
+}
+
+fn is_negative(x: i32) -> bool {
+    x < 0
+}
+
+fn is_positive_or_zero(x: i32) -> bool {
+    x >= 0
+}
+
+fn is_negative_or_zero(x: i32) -> bool {
+    x <= 0
+}
+
+fn main() {
+    let a: bool = is_zero(1);
+    let b: bool = is_not_zero(2);
+    let c: bool = is_positive(3);
+    let d: bool = is_negative(4);
+    let e: bool = is_positive_or_zero(5);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let f: bool = is_negative_or_zero(6);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let g: bool = a || b;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let h: bool = c && d;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/compile.exp b/gcc/testsuite/rust/compile/torture/compile.exp
new file mode 100644
index 00000000000..48da264a47a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/compile.exp
@@ -0,0 +1,33 @@
+# Copyright (C) 2021-2022 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, torture testing.
+
+# 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"
+gcc-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/torture/compound_assignment_expr1.rs b/gcc/testsuite/rust/compile/torture/compound_assignment_expr1.rs
new file mode 100644
index 00000000000..1ff0d24cf8e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/compound_assignment_expr1.rs
@@ -0,0 +1,23 @@
+fn main() {
+    let mut a = 1;
+    let mut b = 2;
+    let mut c = 3;
+    let mut d = 4;
+    let mut e = 5;
+    let mut f = 6;
+    let mut g = 7;
+    let mut h = 8;
+    let mut i = 9;
+    let mut j = 10;
+
+    a += 1;
+    b -= 2;
+    c *= 3;
+    d /= 4;
+    e %= 5;
+    f &= 6;
+    g |= 7;
+    h ^= 8;
+    i <<= 9;
+    j >>= 10;
+}
diff --git a/gcc/testsuite/rust/compile/torture/conditional.rs b/gcc/testsuite/rust/compile/torture/conditional.rs
new file mode 100644
index 00000000000..2bb3a95f033
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/conditional.rs
@@ -0,0 +1,11 @@
+fn main() {
+    let mut x = 5;
+
+    if x == 5 {
+        x = 1;
+    } else if x == 3 {
+        x = 2;
+    } else {
+        x = 3;
+    }
+}
diff --git a/gcc/testsuite/rust/compile/torture/constant1.rs b/gcc/testsuite/rust/compile/torture/constant1.rs
new file mode 100644
index 00000000000..57bcb0b4970
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/constant1.rs
@@ -0,0 +1,9 @@
+const TEST_CONST:i32 = 10;
+
+fn main() {
+    let mut x = TEST_CONST;
+    x = x + 1;
+
+    let mut y = x + TEST_CONST;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/constant2.rs b/gcc/testsuite/rust/compile/torture/constant2.rs
new file mode 100644
index 00000000000..d06324e8e65
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/constant2.rs
@@ -0,0 +1,6 @@
+fn main() {
+    const C: usize = 42;
+
+    let _a = C;
+    let _b: [i32; C] = [0; C];
+}
diff --git a/gcc/testsuite/rust/compile/torture/constant3.rs b/gcc/testsuite/rust/compile/torture/constant3.rs
new file mode 100644
index 00000000000..d2f1dd5b6db
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/constant3.rs
@@ -0,0 +1,10 @@
+fn main() {
+    const A: [i32; 3] = [1, 2, 3];
+    const B: i32 = A[1];
+    const C: usize = 42;
+    const D: i32 = 7;
+
+    let _a = C;
+    let _b: [i32; C] = [0; C];
+    let _c = B + D;
+}
diff --git a/gcc/testsuite/rust/compile/torture/deadcode1.rs b/gcc/testsuite/rust/compile/torture/deadcode1.rs
new file mode 100644
index 00000000000..1ba646f5c56
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/deadcode1.rs
@@ -0,0 +1,22 @@
+fn test1() -> i32 {
+    return 2;
+    // { dg-warning "unreachable expression" "" { target *-*-* } .+1 }
+    1
+}
+
+fn test2(x: i32) -> i32 {
+    if x > 1 {
+        return 5;
+    } else {
+        return 0;
+    }
+    // { dg-warning "unreachable statement" "" { target *-*-* } .+1 }
+    return 1;
+}
+
+fn main() {
+    let call1 = test1();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let call2 = test2(2);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/deadcode2.rs b/gcc/testsuite/rust/compile/torture/deadcode2.rs
new file mode 100644
index 00000000000..ba7d5f015e9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/deadcode2.rs
@@ -0,0 +1,10 @@
+fn foo() -> i32 {
+    return 1;
+
+    let a = -1; // { dg-warning "unreachable statement" }
+    a // { dg-warning "unreachable expression" }
+}
+
+fn main() {
+    foo();
+}
diff --git a/gcc/testsuite/rust/compile/torture/deref1.rs b/gcc/testsuite/rust/compile/torture/deref1.rs
new file mode 100644
index 00000000000..d715ce96c79
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/deref1.rs
@@ -0,0 +1,6 @@
+fn main() {
+    let a = 123;
+    let b = &a;
+    let c = *b;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/deref_function.rs b/gcc/testsuite/rust/compile/torture/deref_function.rs
new file mode 100644
index 00000000000..b1c5ff63423
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/deref_function.rs
@@ -0,0 +1,10 @@
+fn foo() {}
+
+
+fn main() {
+    let _c = *{
+	let _a = foo;
+	let b = &1;
+	b
+    };
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/torture/doc_comment.rs b/gcc/testsuite/rust/compile/torture/doc_comment.rs
new file mode 100644
index 00000000000..f99e41524ae
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/doc_comment.rs
@@ -0,0 +1,16 @@
+/// doc comment 1
+/// doc comment 2
+/// `blah blah` markdown
+pub struct TestStruct {}
+
+#[doc(hidden)]
+pub struct DocAttribute {}
+
+#[doc(a,b)]
+pub struct UnkAttribute {}
+
+fn main() {
+    let _ = TestStruct {};
+    let _ = DocAttribute {};
+    let _ = UnkAttribute {};
+}
diff --git a/gcc/testsuite/rust/compile/torture/enum1.rs b/gcc/testsuite/rust/compile/torture/enum1.rs
new file mode 100644
index 00000000000..7cea48f29e2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/enum1.rs
@@ -0,0 +1,13 @@
+enum Foo {
+    A,
+    B,
+    C(char),
+    D { x: i64, y: i64 },
+}
+
+fn main() {
+    let _a = Foo::A;
+    let _b = Foo::B;
+    let _c = Foo::C('x');
+    let _d = Foo::D { x: 20, y: 80 };
+}
diff --git a/gcc/testsuite/rust/compile/torture/extern_mod1.rs b/gcc/testsuite/rust/compile/torture/extern_mod1.rs
new file mode 100644
index 00000000000..4b576e03d80
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/extern_mod1.rs
@@ -0,0 +1,6 @@
+// { dg-additional-options "-w" }
+mod modules;
+
+fn main() {
+    let twelve = modules::return_12();
+}
diff --git a/gcc/testsuite/rust/compile/torture/extern_mod2.rs b/gcc/testsuite/rust/compile/torture/extern_mod2.rs
new file mode 100644
index 00000000000..4984d5dc2c1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/extern_mod2.rs
@@ -0,0 +1,23 @@
+// { dg-additional-options "-w" }
+
+#[path = "modules/valid_path.rs"]
+mod not_a_valid_path;
+
+#[path ="modules/valid_path.rs"]
+mod path_without_extra_equal;
+
+#[path= "modules/valid_path.rs"]
+mod no_leading_equal;
+
+#[path       =     "modules/valid_path.rs"]
+mod extra_spaces;
+
+#[path] // { dg-error "path attributes must contain a filename" }
+mod error; // { dg-error "no candidate found" }
+
+// This is "valid", and should only error out when parsing
+// the file
+#[path = "not_a_valid_file.rs"]
+mod another_error; // { dg-error "No such file or directory" }
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/torture/float1.rs b/gcc/testsuite/rust/compile/torture/float1.rs
new file mode 100644
index 00000000000..fbe89382267
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/float1.rs
@@ -0,0 +1,9 @@
+fn test(x: f32) -> f32 {
+    return x + 1.0;
+}
+
+fn main() {
+    let a_float = 5.123;
+    let call_test = test(a_float + 1.0);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/float_types.rs b/gcc/testsuite/rust/compile/torture/float_types.rs
new file mode 100644
index 00000000000..7d3d298a1bb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/float_types.rs
@@ -0,0 +1,13 @@
+// { dg-prune-output "warning: unused name" } as there are many of these expected.
+
+fn main() {
+    let a1: f32 = 1.0f32;
+    let a2: f64 = 2.0f64;
+    let a3: f32 = 3f32;
+    let a4: f64 = 4f64;
+
+    let b1 = 1.0f32;
+    let b2 = 2.0f64;
+    let b3 = 3f32;
+    let b4 = 4f64;
+}
diff --git a/gcc/testsuite/rust/compile/torture/forward_decl_1.rs b/gcc/testsuite/rust/compile/torture/forward_decl_1.rs
new file mode 100644
index 00000000000..b8403f9b97f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/forward_decl_1.rs
@@ -0,0 +1,11 @@
+fn main() {
+    let mut an_integer = 5;
+    an_integer = test(1) + 3;
+
+    let call_test = test(1);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
+
+fn test(x: i32) -> i32 {
+    return x + 1;
+}
diff --git a/gcc/testsuite/rust/compile/torture/forward_decl_2.rs b/gcc/testsuite/rust/compile/torture/forward_decl_2.rs
new file mode 100644
index 00000000000..efc3b0dc565
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/forward_decl_2.rs
@@ -0,0 +1,6 @@
+fn main() {
+    let y = x + 1;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
+
+static x: i32 = 3;
diff --git a/gcc/testsuite/rust/compile/torture/forward_decl_3-unsafe.rs b/gcc/testsuite/rust/compile/torture/forward_decl_3-unsafe.rs
new file mode 100644
index 00000000000..04935864f02
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/forward_decl_3-unsafe.rs
@@ -0,0 +1,13 @@
+fn main() {
+    unsafe {
+        let struct_test = Foo { one: 1, two: 2 };
+        // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    };
+}
+
+struct Foo {
+    one: i32,
+    // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+    two: i32,
+    // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/forward_decl_3.rs b/gcc/testsuite/rust/compile/torture/forward_decl_3.rs
new file mode 100644
index 00000000000..9256df5f728
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/forward_decl_3.rs
@@ -0,0 +1,11 @@
+fn main() {
+    let struct_test = Foo { one: 1, two: 2 };
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
+
+struct Foo {
+    one: i32,
+    // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+    two: i32,
+    // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/forward_decl_4.rs b/gcc/testsuite/rust/compile/torture/forward_decl_4.rs
new file mode 100644
index 00000000000..e1fe51f9025
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/forward_decl_4.rs
@@ -0,0 +1,9 @@
+fn main() {
+    let mut x = TEST_CONST;
+    x = x + 1;
+
+    let mut y = x + TEST_CONST;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
+
+const TEST_CONST: i32 = 10;
diff --git a/gcc/testsuite/rust/compile/torture/forward_decl_5.rs b/gcc/testsuite/rust/compile/torture/forward_decl_5.rs
new file mode 100644
index 00000000000..73a47fe061b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/forward_decl_5.rs
@@ -0,0 +1,19 @@
+pub fn main() {
+    let a;
+    a = foo { a: 123, b: 456f32 };
+
+    let mut a = 123;
+    a = bar(a);
+
+    let mut b = 456f32;
+    b = bar(b);
+
+    fn bar<T>(x: T) -> T {
+        x
+    }
+
+    struct foo {
+        a: i32,
+        b: f32,
+    };
+}
diff --git a/gcc/testsuite/rust/compile/torture/func1.rs b/gcc/testsuite/rust/compile/torture/func1.rs
new file mode 100644
index 00000000000..df1789e7bbe
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/func1.rs
@@ -0,0 +1,7 @@
+fn not_void() -> i32 {
+    8
+}
+
+fn main() {
+    not_void();
+}
diff --git a/gcc/testsuite/rust/compile/torture/func2.rs b/gcc/testsuite/rust/compile/torture/func2.rs
new file mode 100644
index 00000000000..f7dd556d955
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/func2.rs
@@ -0,0 +1,20 @@
+fn foo() {
+    8;
+    8;
+}
+
+fn bar() -> i32 {
+    8;
+    8
+}
+
+fn baz() -> i32 {
+    8;
+    return 8;
+}
+
+fn main() {
+    let a = foo(); // { dg-warning "unused name" }
+    let b = bar(); // { dg-warning "unused name" }
+    let c = baz(); // { dg-warning "unused name" }
+}
diff --git a/gcc/testsuite/rust/compile/torture/function_reference1.rs b/gcc/testsuite/rust/compile/torture/function_reference1.rs
new file mode 100644
index 00000000000..dfbd01bdbdc
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/function_reference1.rs
@@ -0,0 +1,9 @@
+fn test(a: i32) -> i32 {
+    a + 1
+}
+
+fn main() {
+    let a = test;
+    let b = a(1);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/function_reference2.rs b/gcc/testsuite/rust/compile/torture/function_reference2.rs
new file mode 100644
index 00000000000..3c3e7c10910
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/function_reference2.rs
@@ -0,0 +1,9 @@
+fn test(a: i32) -> i32 {
+    a + 1
+}
+
+fn main() {
+    let a: fn(i32) -> i32 = test;
+    let b = a(1);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/function_reference3.rs b/gcc/testsuite/rust/compile/torture/function_reference3.rs
new file mode 100644
index 00000000000..0cb3181f4a1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/function_reference3.rs
@@ -0,0 +1,20 @@
+struct Foo {
+    a: fn(i32) -> i32,
+    b: i32,
+}
+
+fn test(a: i32) -> i32 {
+    a + 1
+}
+
+fn main() {
+    let a = test(1);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let b: fn(i32) -> i32 = test;
+    let c = b(1);
+
+    let d = Foo { a: test, b: c };
+    let e = (d.a)(d.b);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/function_reference4.rs b/gcc/testsuite/rust/compile/torture/function_reference4.rs
new file mode 100644
index 00000000000..977e4c97215
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/function_reference4.rs
@@ -0,0 +1,9 @@
+fn test(a: i32) -> i32 {
+    a + 1
+}
+
+fn main() {
+    let a: fn(_) -> _ = test;
+    let b = a(1);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics1.rs b/gcc/testsuite/rust/compile/torture/generics1.rs
new file mode 100644
index 00000000000..87bcdc8f305
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics1.rs
@@ -0,0 +1,51 @@
+struct Foo {
+    a: f32,
+    b: bool,
+}
+
+struct GenericStruct<T> {
+    a: T,
+    b: usize,
+}
+
+fn main() {
+    let a1;
+    a1 = Foo { a: 1.0, b: false };
+
+    let b1: f32 = a1.a;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let c1: bool = a1.b;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let a2: GenericStruct<i8>;
+    a2 = GenericStruct::<i8> { a: 1, b: 456 };
+
+    let b2: i8 = a2.a;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let c2: usize = a2.b;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let a3;
+    a3 = GenericStruct::<i32> { a: 123, b: 456 };
+
+    let b3: i32 = a3.a;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let c3: usize = a3.b;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let a4;
+    a4 = GenericStruct { a: 1.0, b: 456 };
+
+    let b4: f32 = a4.a;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let c4: usize = a4.b;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let a5;
+    a5 = GenericStruct::<_> { a: true, b: 456 };
+
+    let b5: bool = a5.a;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let c5: usize = a5.b;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics10.rs b/gcc/testsuite/rust/compile/torture/generics10.rs
new file mode 100644
index 00000000000..8473d49587b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics10.rs
@@ -0,0 +1,20 @@
+struct Foo<T>(T);
+
+struct Bar<T> {
+    a: Foo<T>,
+    b: bool,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+fn test<T>(a: Bar<T>) -> Foo<T> {
+    a.a
+}
+
+fn main() {
+    let a: Bar<i32> = Bar::<i32> {
+        a: Foo::<i32>(123),
+        b: true,
+    };
+    let b: Foo<i32> = test(a);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics11.rs b/gcc/testsuite/rust/compile/torture/generics11.rs
new file mode 100644
index 00000000000..3c8f5ba0058
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics11.rs
@@ -0,0 +1,8 @@
+struct Foo<T>(T, u32);
+
+type TypeAlias = Foo<i32>;
+
+fn main() {
+    let a: Foo<i32>;
+    a = TypeAlias { 0: 123, 1: 456 };
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics12.rs b/gcc/testsuite/rust/compile/torture/generics12.rs
new file mode 100644
index 00000000000..f31be584e09
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics12.rs
@@ -0,0 +1,17 @@
+struct GenericStruct<T>(T, usize);
+
+impl GenericStruct<i32> {
+    fn new(a: i32, b: usize) -> Self {
+        GenericStruct(a, b)
+    }
+
+    fn get(self) -> i32 {
+        self.0
+    }
+}
+
+fn main() {
+    let a: GenericStruct<i32> = GenericStruct::<i32>::new(123, 456);
+    let aa: i32 = a.get();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics13.rs b/gcc/testsuite/rust/compile/torture/generics13.rs
new file mode 100644
index 00000000000..9eb598f02a8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics13.rs
@@ -0,0 +1,41 @@
+struct Foo<A> {
+    a: A,
+    // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+struct GenericStruct<T> {
+    a: T,
+    b: usize,
+}
+
+impl Foo<isize> {
+    fn test() -> i32 {
+        123
+    }
+
+    fn bar(self) -> isize {
+        // { dg-warning "associated function is never used" "" { target *-*-* } .-1 }
+        self.a
+    }
+}
+
+fn main() {
+    let a: i32 = Foo::test();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let a2: GenericStruct<i8>;
+    a2 = GenericStruct::<i8> { a: 1, b: 456 };
+
+    let b2: i8 = a2.a;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let c2: usize = a2.b;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let a4;
+    a4 = GenericStruct { a: 1.0, b: 456 };
+
+    let b4: f32 = a4.a;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let c4: usize = a4.b;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics14.rs b/gcc/testsuite/rust/compile/torture/generics14.rs
new file mode 100644
index 00000000000..e51a4079e30
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics14.rs
@@ -0,0 +1,20 @@
+struct Foo<A> {
+    a: A,
+    // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+impl Foo<isize> {
+    fn test() -> i32 {
+        123
+    }
+
+    fn bar(self) -> isize {
+        // { dg-warning "associated function is never used" "" { target *-*-* } .-1 }
+        self.a
+    }
+}
+
+fn main() {
+    let a: i32 = Foo::test();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics15.rs b/gcc/testsuite/rust/compile/torture/generics15.rs
new file mode 100644
index 00000000000..c16a67c4dd5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics15.rs
@@ -0,0 +1,23 @@
+struct Foo<T>(T, bool);
+
+impl Foo<i32> {
+    fn bar(self) -> i32 {
+        self.0
+    }
+}
+
+impl Foo<f32> {
+    fn bar(self) -> f32 {
+        self.0
+    }
+}
+
+fn main() {
+    let a = Foo(123, true);
+    let aa = a.bar();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let b = Foo(456f32, true);
+    let bb = b.bar();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics16.rs b/gcc/testsuite/rust/compile/torture/generics16.rs
new file mode 100644
index 00000000000..15b9d7b55e7
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics16.rs
@@ -0,0 +1,31 @@
+struct Foo<T>(T, bool);
+
+impl Foo<i32> {
+    fn new() -> Self {
+        Foo(123, true)
+    }
+
+    fn bar(self) -> i32 {
+        self.0
+    }
+}
+
+impl Foo<f32> {
+    fn new() -> Self {
+        Foo(123f32, true)
+    }
+
+    fn bar(self) -> f32 {
+        self.0
+    }
+}
+
+fn main() {
+    let a = Foo::<i32>::new();
+    let aa: i32 = a.bar();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let b = Foo::<f32>::new();
+    let bb: f32 = b.bar();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics17.rs b/gcc/testsuite/rust/compile/torture/generics17.rs
new file mode 100644
index 00000000000..d52314999b9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics17.rs
@@ -0,0 +1,19 @@
+struct Foo<T>(T);
+
+impl<X> Foo<X> {
+    fn new(a: X) -> Self {
+        Self(a)
+    }
+
+    fn test(self) -> X {
+        self.0
+    }
+}
+
+fn main() {
+    let a;
+    a = Foo::new(123);
+
+    let b = a.test();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics18.rs b/gcc/testsuite/rust/compile/torture/generics18.rs
new file mode 100644
index 00000000000..4c98b86a1b9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics18.rs
@@ -0,0 +1,20 @@
+struct Foo<T>(T);
+
+impl<X> Foo<X> {
+    fn new(a: X) -> Self {
+        // { dg-warning "associated function is never used" "" { target *-*-* } .-1 }
+        Self(a)
+    }
+
+    fn test(self) -> X {
+        self.0
+    }
+}
+
+fn main() {
+    let a;
+    a = Foo(123);
+
+    let b = a.test();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics19.rs b/gcc/testsuite/rust/compile/torture/generics19.rs
new file mode 100644
index 00000000000..9a5b4cb48dc
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics19.rs
@@ -0,0 +1,12 @@
+struct Foo<X, Y>(X, Y);
+
+impl<T> Foo<u32, T> {
+    fn new(a: T) -> Self {
+        Self(123, a)
+    }
+}
+
+fn main() {
+    let a;
+    a = Foo::new(false);
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics2.rs b/gcc/testsuite/rust/compile/torture/generics2.rs
new file mode 100644
index 00000000000..da0ab992243
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics2.rs
@@ -0,0 +1,45 @@
+struct Foo(f32, bool);
+
+struct GenericStruct<T>(T, usize);
+
+fn main() {
+    let a1;
+    a1 = Foo(1.0, false);
+
+    let b1: f32 = a1.0;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let c1: bool = a1.1;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let a2: GenericStruct<i8>;
+    a2 = GenericStruct::<i8>(1, 456);
+
+    let b2: i8 = a2.0;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let c2: usize = a2.1;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let a3;
+    a3 = GenericStruct::<i32>(123, 456);
+
+    let b3: i32 = a3.0;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let c3: usize = a3.1;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let a4;
+    a4 = GenericStruct(1.0, 456);
+
+    let b4: f32 = a4.0;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let c4: usize = a4.1;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let a5;
+    a5 = GenericStruct::<_>(true, 456);
+
+    let b5: bool = a5.0;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let c5: usize = a5.1;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics20.rs b/gcc/testsuite/rust/compile/torture/generics20.rs
new file mode 100644
index 00000000000..8fe1cffdf7d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics20.rs
@@ -0,0 +1,12 @@
+struct Foo<A, B>(A, B);
+
+impl<T> Foo<T, T> {
+    fn new(a: T, b: T) -> Self {
+        Self(a, b)
+    }
+}
+
+fn main() {
+    let a;
+    a = Foo::new(123, 456);
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics21.rs b/gcc/testsuite/rust/compile/torture/generics21.rs
new file mode 100644
index 00000000000..dc4e935cac7
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics21.rs
@@ -0,0 +1,13 @@
+fn callee<T>(t: &T) -> i32 {
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    32
+}
+
+fn caller(t: i32) -> i32 {
+    callee(&t)
+}
+
+fn main() {
+    let a;
+    a = caller(123);
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics22.rs b/gcc/testsuite/rust/compile/torture/generics22.rs
new file mode 100644
index 00000000000..465ebb0f5e1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics22.rs
@@ -0,0 +1,13 @@
+fn callee<T>(t: (T, bool)) -> i32 {
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    32
+}
+
+fn caller(t: i32) -> i32 {
+    callee((t, false))
+}
+
+fn main() {
+    let a;
+    a = caller(123);
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics23.rs b/gcc/testsuite/rust/compile/torture/generics23.rs
new file mode 100644
index 00000000000..2169e3649c6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics23.rs
@@ -0,0 +1,6 @@
+struct Foo<A = f32>(A);
+
+fn main() {
+    let a: Foo;
+    a = Foo(123f32);
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics24.rs b/gcc/testsuite/rust/compile/torture/generics24.rs
new file mode 100644
index 00000000000..0de45a8c404
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics24.rs
@@ -0,0 +1,34 @@
+struct Foo<A = (isize, char)> {
+    a: A,
+}
+
+impl Foo<isize> {
+    fn bar(self) -> isize {
+        self.a
+    }
+}
+
+impl Foo<char> {
+    fn bar(self) -> char {
+        // { dg-warning "associated function is never used" "" { target *-*-* } .-1 }
+        self.a
+    }
+}
+
+impl Foo {
+    fn bar(self) {
+        let a: (isize, char) = self.a;
+        let b = a.0;
+        let c = a.1;
+        // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+        let aa: Foo<isize> = Foo { a: b };
+        let bb: isize = aa.bar();
+        // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    }
+}
+
+fn main() {
+    let a = Foo { a: (123, 'a') };
+    a.bar();
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics25.rs b/gcc/testsuite/rust/compile/torture/generics25.rs
new file mode 100644
index 00000000000..e7792e3efb3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics25.rs
@@ -0,0 +1,9 @@
+struct Foo<A, B = (A, A)>(A, B);
+
+fn main() {
+    let a: Foo<bool>;
+    a = Foo::<bool>(true, (false, true));
+
+    let b: (bool, bool);
+    b = a.1;
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics26.rs b/gcc/testsuite/rust/compile/torture/generics26.rs
new file mode 100644
index 00000000000..522e16f32f7
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics26.rs
@@ -0,0 +1,21 @@
+// github issue #415
+fn test<A, B>(a: A, b: B) -> (A, B) {
+    (a, b)
+}
+
+fn main() {
+    let a = test::<i32, i32>(123, 456);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let b = test::<f32, f32>(123f32, 456f32);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let c = test::<_, _>(123, 456f32);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let d = test(true, 1234);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let e = test((123, false), 123f32);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics27.rs b/gcc/testsuite/rust/compile/torture/generics27.rs
new file mode 100644
index 00000000000..9871638dd9f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics27.rs
@@ -0,0 +1,16 @@
+// github issue #415
+fn test<A>(a: &A) -> &A {
+    a
+}
+
+fn main() {
+    let a = 123;
+    let b = &a;
+    let c = test(b);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let a = 123f32;
+    let b = &a;
+    let c = test(b);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics28.rs b/gcc/testsuite/rust/compile/torture/generics28.rs
new file mode 100644
index 00000000000..8cee8b00fb2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics28.rs
@@ -0,0 +1,18 @@
+struct Foo<A, B>(A, B);
+
+impl Foo<i32, f32> {
+    fn test<X>(a: X) -> X {
+        a
+    }
+}
+
+fn main() {
+    let a;
+    a = Foo::test::<_>(123);
+
+    let b;
+    b = Foo::test::<bool>(true);
+
+    let c;
+    c = Foo::test(456f32);
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics29.rs b/gcc/testsuite/rust/compile/torture/generics29.rs
new file mode 100644
index 00000000000..e09a1044574
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics29.rs
@@ -0,0 +1,16 @@
+struct Foo<A, B>(A, B);
+
+impl Foo<i32, f32> {
+    fn test<X>(self, a: X) -> X {
+        // { dg-warning "unused name" "" { target *-*-* } .-1 }
+        a
+    }
+}
+
+fn main() {
+    let a;
+    a = Foo(123, 456f32);
+
+    let b;
+    b = a.test::<bool>(false);
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics3.rs b/gcc/testsuite/rust/compile/torture/generics3.rs
new file mode 100644
index 00000000000..ceec8f7d9c6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics3.rs
@@ -0,0 +1,15 @@
+fn test<T>(a: T) -> T {
+    a
+}
+
+fn main() {
+    let a;
+    a = test(123);
+    let aa: i32 = a;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let b;
+    b = test::<u32>(456);
+    let bb: u32 = b;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics30.rs b/gcc/testsuite/rust/compile/torture/generics30.rs
new file mode 100644
index 00000000000..229f6d1254b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics30.rs
@@ -0,0 +1,16 @@
+struct Foo<A, B>(A, B);
+
+impl<T> Foo<T, f32> {
+    fn test<X>(self, a: X) -> X {
+        // { dg-warning "unused name" "" { target *-*-* } .-1 }
+        a
+    }
+}
+
+fn main() {
+    let a;
+    a = Foo(123, 456f32);
+
+    let b;
+    b = a.test::<bool>(false);
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics31.rs b/gcc/testsuite/rust/compile/torture/generics31.rs
new file mode 100644
index 00000000000..68ad4bf9a96
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics31.rs
@@ -0,0 +1,15 @@
+struct Foo<A, B>(A, B);
+
+impl<T> Foo<T, f32> {
+    fn test<X>(self, a: X) -> (T, X) {
+        (self.0, a)
+    }
+}
+
+fn main() {
+    let a;
+    a = Foo(123, 456f32);
+
+    let b;
+    b = a.test::<bool>(false);
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics32.rs b/gcc/testsuite/rust/compile/torture/generics32.rs
new file mode 100644
index 00000000000..21b9cae7409
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics32.rs
@@ -0,0 +1,15 @@
+struct Foo<A, B>(A, B);
+
+impl<T> Foo<T, f32> {
+    fn test<X>(self, a: X) -> (T, X) {
+        (self.0, a)
+    }
+}
+
+fn main() {
+    let a;
+    a = Foo(123, 456f32);
+
+    let b;
+    b = a.test(false);
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics4.rs b/gcc/testsuite/rust/compile/torture/generics4.rs
new file mode 100644
index 00000000000..915cc49c68b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics4.rs
@@ -0,0 +1,17 @@
+struct Foo<T> {
+    a: T,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+    b: bool,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+fn test<T>(a: T) -> Foo<T> {
+    Foo { a: a, b: true }
+}
+
+fn main() {
+    let a: Foo<i32> = test(123);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let b: Foo<u32> = test(456);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics5.rs b/gcc/testsuite/rust/compile/torture/generics5.rs
new file mode 100644
index 00000000000..b7f43028992
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics5.rs
@@ -0,0 +1,10 @@
+fn test<T>(a: T) -> T {
+    a
+}
+
+fn main() {
+    let a: i32 = test(123);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let b: i32 = test(456);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics6.rs b/gcc/testsuite/rust/compile/torture/generics6.rs
new file mode 100644
index 00000000000..5456b6dcb97
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics6.rs
@@ -0,0 +1,16 @@
+struct Foo<T>(T);
+
+struct Bar<T> {
+    a: Foo<T>,
+    b: bool,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+fn main() {
+    let a: Bar<i32> = Bar::<i32> {
+        a: Foo::<i32>(123),
+        b: true,
+    };
+    let b: i32 = a.a.0;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics7.rs b/gcc/testsuite/rust/compile/torture/generics7.rs
new file mode 100644
index 00000000000..e8e5ca69c3d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics7.rs
@@ -0,0 +1,14 @@
+struct Foo<T>(T);
+
+struct Bar {
+    a: Foo<i32>,
+    b: bool,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+fn main() {
+    let a = Foo::<i32>(123);
+    let b: Bar = Bar { a: a, b: true };
+    let c: i32 = b.a.0;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics8.rs b/gcc/testsuite/rust/compile/torture/generics8.rs
new file mode 100644
index 00000000000..036d85568f0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics8.rs
@@ -0,0 +1,18 @@
+struct GenericStruct<T>(T, usize);
+
+impl<T> GenericStruct<T> {
+    fn new(a: T, b: usize) -> Self {
+        GenericStruct(a, b)
+    }
+}
+
+fn main() {
+    let a: GenericStruct<i32> = GenericStruct::<i32>::new(123, 456);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let b: GenericStruct<u32> = GenericStruct::<_>::new(123, 456);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let c: GenericStruct<f32> = GenericStruct::new(123f32, 456);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/generics9.rs b/gcc/testsuite/rust/compile/torture/generics9.rs
new file mode 100644
index 00000000000..307c34f3e9b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/generics9.rs
@@ -0,0 +1,25 @@
+struct GenericStruct<T>(T, usize);
+
+impl<T> GenericStruct<T> {
+    fn new(a: T, b: usize) -> Self {
+        GenericStruct(a, b)
+    }
+
+    fn get(self) -> T {
+        self.0
+    }
+}
+
+fn main() {
+    let a: GenericStruct<i32> = GenericStruct::<i32>::new(123, 456);
+    let aa: i32 = a.get();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let b: GenericStruct<u32> = GenericStruct::<_>::new(123, 456);
+    let bb: u32 = b.get();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let c: GenericStruct<f32> = GenericStruct::new(123f32, 456);
+    let cc: f32 = c.get();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/grouped_expr_function.rs b/gcc/testsuite/rust/compile/torture/grouped_expr_function.rs
new file mode 100644
index 00000000000..eca7178b7f7
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/grouped_expr_function.rs
@@ -0,0 +1,6 @@
+fn foo() {}
+
+
+fn main() {
+    let _a = (foo());
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/torture/identifier-missing-impl-1.rs b/gcc/testsuite/rust/compile/torture/identifier-missing-impl-1.rs
new file mode 100644
index 00000000000..2389fa52bfd
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/identifier-missing-impl-1.rs
@@ -0,0 +1,19 @@
+struct I();
+
+impl I {
+    fn () {
+        // { dg-error {expecting 'identifier' but '\(' found} "" { target *-*-* } .-1 }
+        // { dg-error {failed to parse inherent impl item in inherent impl} "" { target *-*-* } .-2 }
+        // { dg-error {failed to parse item in crate} "" { target *-*-* } .-3 }
+    }
+}
+
+impl I {
+    unsafe fn () {
+        // { dg-error {expecting 'identifier' but '\(' found} "" { xfail *-*-* } .-1 }
+    }
+}
+
+fn main() {
+    let _i = I();
+}
diff --git a/gcc/testsuite/rust/compile/torture/if.rs b/gcc/testsuite/rust/compile/torture/if.rs
new file mode 100644
index 00000000000..bcd520f66a9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/if.rs
@@ -0,0 +1,19 @@
+fn foo() -> bool {
+    true
+}
+
+fn bar() {}
+
+struct Foo1 {
+    one: i32
+}
+
+
+fn main() {
+    if foo() {
+        bar();
+        let a = Foo1{one: 1};
+        a.one
+    }
+
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/torture/if_elif.rs b/gcc/testsuite/rust/compile/torture/if_elif.rs
new file mode 100644
index 00000000000..a89ad5eb02f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/if_elif.rs
@@ -0,0 +1,20 @@
+fn foo() -> bool {
+    true
+}
+
+fn bar() -> bool {
+    false
+}
+
+struct Foo1 {
+    one: i32
+}
+
+
+fn main() {
+    if foo() {
+    } else if bar() {
+        let a = Foo1{one: 1};
+        a.one;
+    }
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/torture/if_elif_else_expr1.rs b/gcc/testsuite/rust/compile/torture/if_elif_else_expr1.rs
new file mode 100644
index 00000000000..65ed7f7a23a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/if_elif_else_expr1.rs
@@ -0,0 +1,14 @@
+fn test(x: i32) -> i32 {
+    if x == 10 {
+        123
+    } else if x < 10 {
+        456
+    } else {
+        789
+    }
+}
+
+fn main() {
+    let a = test(1);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/if_else.rs b/gcc/testsuite/rust/compile/torture/if_else.rs
new file mode 100644
index 00000000000..09aecaed4d6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/if_else.rs
@@ -0,0 +1,19 @@
+fn foo() -> bool {
+    true
+}
+
+fn bar() {}
+
+struct Foo1 {
+    one: i32
+}
+
+
+fn main() {
+    if foo() {
+        bar();
+    } else {
+        let a = Foo1{one: 1};
+        a.one;
+    }
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/torture/ifunaryexpr.rs b/gcc/testsuite/rust/compile/torture/ifunaryexpr.rs
new file mode 100644
index 00000000000..8f0bb87f558
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/ifunaryexpr.rs
@@ -0,0 +1,22 @@
+extern "C"
+{
+  pub fn abort ();
+}
+
+struct B { b: bool }
+
+pub fn main ()
+{
+  let n = 1;
+  if 0 > -n { } else { unsafe { abort (); } }
+
+  let b = true;
+  if !b { unsafe { abort (); } }
+  if !!b { } else { unsafe { abort (); } }
+
+  let bb = B { b: false };
+
+  if !bb.b && !b { unsafe { abort (); } }
+
+  if (B { b: true }).b { } else { unsafe { abort (); } }
+}
diff --git a/gcc/testsuite/rust/compile/torture/impl_block1.rs b/gcc/testsuite/rust/compile/torture/impl_block1.rs
new file mode 100644
index 00000000000..d67afa187b1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/impl_block1.rs
@@ -0,0 +1,23 @@
+struct Foo(i32, bool);
+
+impl Foo {
+    fn new(a: i32, b: bool) -> Foo {
+        Foo(a, b)
+    }
+
+    fn test2() -> i32 {
+        test_forward_decl()
+    }
+}
+
+fn test_forward_decl() -> i32 {
+    123
+}
+
+fn main() {
+    let a;
+    a = Foo::new(1, true);
+
+    let b;
+    b = Foo::test2();
+}
diff --git a/gcc/testsuite/rust/compile/torture/impl_block2.rs b/gcc/testsuite/rust/compile/torture/impl_block2.rs
new file mode 100644
index 00000000000..0ed592d07be
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/impl_block2.rs
@@ -0,0 +1,28 @@
+struct Foo(i32, bool);
+
+impl Foo {
+    const number: i32 = 456;
+
+    fn new(a: i32, b: bool) -> Foo {
+        Foo(a, b)
+    }
+
+    fn test2() -> i32 {
+        test_forward_decl()
+    }
+}
+
+fn test_forward_decl() -> i32 {
+    123
+}
+
+fn main() {
+    let a;
+    a = Foo::new(1, true);
+
+    let b;
+    b = Foo::test2();
+
+    let c;
+    c = Foo::new(Foo::number, true);
+}
diff --git a/gcc/testsuite/rust/compile/torture/impl_block3.rs b/gcc/testsuite/rust/compile/torture/impl_block3.rs
new file mode 100644
index 00000000000..22ce19f704d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/impl_block3.rs
@@ -0,0 +1,36 @@
+struct Point {
+    x: f64,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+    y: f64,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+impl Point {
+    fn origin() -> Point {
+        Point { x: 0.0, y: 0.0 }
+    }
+
+    fn new(x: f64, y: f64) -> Point {
+        Point { x: x, y: y }
+    }
+}
+
+struct Rectangle {
+    p1: Point,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+    p2: Point,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+impl Rectangle {
+    fn from(p1: Point, p2: Point) -> Self {
+        Self { p1, p2 }
+    }
+}
+
+fn main() {
+    let p1 = Point::origin();
+    let p2 = Point::new(3.0, 4.0);
+    let rect = Rectangle::from(p1, p2);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/impl_block_unused.rs b/gcc/testsuite/rust/compile/torture/impl_block_unused.rs
new file mode 100644
index 00000000000..fea86319243
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/impl_block_unused.rs
@@ -0,0 +1,17 @@
+struct Foo(i32, bool);
+
+impl Foo {
+    fn new(a: i32, b: bool) -> Foo {
+        // { dg-warning "associated function is never used" "" { target *-*-* } .-1 }
+        Foo(a, b)
+    }
+
+    fn test2() -> i32 {
+        // { dg-warning "associated function is never used" "" { target *-*-* } .-1 }
+        1
+    }
+}
+
+fn main() {
+    let _a = Foo(1, true);
+}
diff --git a/gcc/testsuite/rust/compile/torture/implicit_returns1.rs b/gcc/testsuite/rust/compile/torture/implicit_returns1.rs
new file mode 100644
index 00000000000..54cc8b3aea8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/implicit_returns1.rs
@@ -0,0 +1,73 @@
+fn test1() -> i32 {
+    1
+}
+
+fn test2() -> i32 {
+    return 2;
+}
+
+fn test3(x: i32) -> i32 {
+    if x > 1 {
+        5
+    } else {
+        0
+    }
+}
+
+fn test4(x: i32) -> i32 {
+    if x > 1 {
+        return 1;
+    }
+    0
+}
+
+fn test5(x: i32) -> i32 {
+    if x > 1 {
+        if x == 5 {
+            7
+        } else {
+            9
+        }
+    } else {
+        0
+    }
+}
+
+fn test6(x: i32) -> i32 {
+    if x > 1 {
+        return 5;
+    } else {
+        return 0;
+    }
+}
+
+fn test7(x: i32) -> i32 {
+    if x > 1 {
+        return 5;
+    } else {
+        return 0;
+    }
+}
+
+fn test8() -> i32 {
+    return 1;
+}
+
+fn main() {
+    let call1 = test1();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let call2 = test2();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let call3 = test3(3);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let call4 = test4(4);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let call5 = test5(5);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let call6 = test6(6);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let call7 = test7(7);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let call8 = test8();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/infer_type1.rs b/gcc/testsuite/rust/compile/torture/infer_type1.rs
new file mode 100644
index 00000000000..aabfcef895b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/infer_type1.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let array: [_; 2] = [111, 222];
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/inner_attributes.rs b/gcc/testsuite/rust/compile/torture/inner_attributes.rs
new file mode 100644
index 00000000000..3410dd6ec87
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/inner_attributes.rs
@@ -0,0 +1,3 @@
+#![allow(dead_code)]
+#![allow(unused_variables)]
+pub fn main () { }
diff --git a/gcc/testsuite/rust/compile/torture/integer_inference_var1.rs b/gcc/testsuite/rust/compile/torture/integer_inference_var1.rs
new file mode 100644
index 00000000000..ccee06aad10
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/integer_inference_var1.rs
@@ -0,0 +1,6 @@
+const TEST_CONST: i32 = 10;
+
+fn main() {
+    let a;
+    a = TEST_CONST;
+}
diff --git a/gcc/testsuite/rust/compile/torture/integer_inference_var2.rs b/gcc/testsuite/rust/compile/torture/integer_inference_var2.rs
new file mode 100644
index 00000000000..2209e937479
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/integer_inference_var2.rs
@@ -0,0 +1,6 @@
+fn main() {
+    let a = 1u32;
+
+    let b;
+    b = a;
+}
diff --git a/gcc/testsuite/rust/compile/torture/integer_inference_var3.rs b/gcc/testsuite/rust/compile/torture/integer_inference_var3.rs
new file mode 100644
index 00000000000..582ae77caa4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/integer_inference_var3.rs
@@ -0,0 +1,11 @@
+fn test(a: u32) -> u32 {
+    a + 1
+}
+
+fn main() {
+    let param;
+    param = 123;
+
+    let a = test(param);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/integer_inference_var4.rs b/gcc/testsuite/rust/compile/torture/integer_inference_var4.rs
new file mode 100644
index 00000000000..136d8183d08
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/integer_inference_var4.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let a;
+    a = 1;
+}
diff --git a/gcc/testsuite/rust/compile/torture/integer_inference_var5.rs b/gcc/testsuite/rust/compile/torture/integer_inference_var5.rs
new file mode 100644
index 00000000000..051de1d6520
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/integer_inference_var5.rs
@@ -0,0 +1,25 @@
+const TEST_CONST: i32 = 10;
+
+fn test(x: u32) -> u32 {
+    x + 1
+}
+
+fn main() {
+    let x = TEST_CONST;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let a = 1u32;
+    let b = a;
+
+    let c;
+    c = 1;
+
+    let d;
+    d = b;
+
+    let param;
+    param = 123;
+
+    let test_call = test(param);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/integer_types.rs b/gcc/testsuite/rust/compile/torture/integer_types.rs
new file mode 100644
index 00000000000..95a73780bb1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/integer_types.rs
@@ -0,0 +1,27 @@
+// { dg-prune-output "warning: unused name" } as there are many of these expected.
+
+fn main() {
+    let a1: i8 = 1i8;
+    let a2: i16 = 2i16;
+    let a3: i32 = 3i32;
+    let a4: i64 = 4i64;
+    let a5: i128 = 5i128;
+
+    let b1 = 1i8;
+    let b2 = 2i16;
+    let b3 = 3i32;
+    let b4 = 4i64;
+    let b5 = 5i128;
+
+    let c1: u8 = 1u8;
+    let c2: u16 = 2u16;
+    let c3: u32 = 3u32;
+    let c4: u64 = 4u64;
+    let c5: u128 = 5u128;
+
+    let d1 = 1u8;
+    let d2 = 2u16;
+    let d3 = 3u32;
+    let d4 = 4u64;
+    let d5 = 5u128;
+}
diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-1.rs b/gcc/testsuite/rust/compile/torture/intrinsics-1.rs
new file mode 100644
index 00000000000..6704c0210d1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/intrinsics-1.rs
@@ -0,0 +1,22 @@
+// { dg-additional-options -fdump-tree-original }
+
+#![feature(intrinsics)]
+
+extern "rust-intrinsic" {
+    pub fn sqrtf32(x: f32) -> f32;
+    pub fn sinf32(x: f32) -> f32;
+}
+
+fn main() {
+    unsafe fn foo() {
+        let mut f32;
+
+        f32 = sqrtf32(5f32);
+        // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_sqrtf \(5\.0e\+0\);$} 1 original } }
+
+        f32 = sinf32(39f32);
+        // { dg-final { scan-tree-dump-times {(?n)f32 = __builtin_sinf \(3\.9e\+1\);$} 1 original } }
+    }
+
+    unsafe { foo() };
+}
diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-2.rs b/gcc/testsuite/rust/compile/torture/intrinsics-2.rs
new file mode 100644
index 00000000000..6b2339f38f3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/intrinsics-2.rs
@@ -0,0 +1,22 @@
+// { dg-additional-options -fdump-tree-original }
+
+#![feature(intrinsics)]
+
+extern "rust-intrinsic" {
+    pub fn size_of<T>() -> usize;
+}
+
+fn main() -> i32 {
+    unsafe fn foo() -> usize {
+        let f: f32;
+
+        let s_f32 = size_of::<f32>();
+        let s_f64 = size_of::<f64>();
+        let s_f32_again = size_of::<f32>();
+
+        s_f32 + s_f64 + s_f32_again
+    }
+
+    // useless code, just used for function compilation caching
+    unsafe { foo() as i32 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/isolated_cr_block_comment.rs b/gcc/testsuite/rust/compile/torture/isolated_cr_block_comment.rs
new file mode 100644
index 00000000000..9a1e090f330
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/isolated_cr_block_comment.rs
@@ -0,0 +1,2 @@
+/* comment cr
 is allowed */
+pub fn main () { }
diff --git a/gcc/testsuite/rust/compile/torture/isolated_cr_line_comment.rs b/gcc/testsuite/rust/compile/torture/isolated_cr_line_comment.rs
new file mode 100644
index 00000000000..4e921a225c2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/isolated_cr_line_comment.rs
@@ -0,0 +1,2 @@
+// comment cr
 is allowed
+pub fn main () { }
diff --git a/gcc/testsuite/rust/compile/torture/issue-1024.rs b/gcc/testsuite/rust/compile/torture/issue-1024.rs
new file mode 100644
index 00000000000..109540934a8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/issue-1024.rs
@@ -0,0 +1,11 @@
+extern "rust-intrinsic" {
+    pub fn size_of<T>() -> usize;
+}
+
+fn test() -> usize {
+    unsafe { size_of::<i32>() }
+}
+
+fn main() {
+    let _a = test();
+}
diff --git a/gcc/testsuite/rust/compile/torture/issue-1075.rs b/gcc/testsuite/rust/compile/torture/issue-1075.rs
new file mode 100644
index 00000000000..7c0a0434262
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/issue-1075.rs
@@ -0,0 +1,42 @@
+// { dg-additional-options "-w" }
+extern "rust-intrinsic" {
+    #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
+    pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
+}
+
+struct FatPtr<T> {
+    data: *const T,
+    len: usize,
+}
+
+union Repr<T> {
+    rust: *const [T],
+    rust_mut: *mut [T],
+    raw: FatPtr<T>,
+}
+
+impl<T> *const [T] {
+    pub const fn len(self) -> usize {
+        // SAFETY: this is safe because `*const [T]` and `FatPtr<T>` have the same layout.
+        // Only `std` can make this guarantee.
+        unsafe { Repr { rust: self }.raw.len }
+    }
+
+    pub const fn as_ptr(self) -> *const T {
+        self as *const T
+    }
+}
+
+impl<T> *const T {
+    pub const unsafe fn offset(self, count: isize) -> *const T {
+        unsafe { offset(self, count) }
+    }
+
+    pub const unsafe fn add(self, count: usize) -> Self {
+        unsafe { self.offset(count as isize) }
+    }
+
+    pub const fn as_ptr(self) -> *const T {
+        self as *const T
+    }
+}
diff --git a/gcc/testsuite/rust/compile/torture/issue-1432.rs b/gcc/testsuite/rust/compile/torture/issue-1432.rs
new file mode 100644
index 00000000000..083a369d16f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/issue-1432.rs
@@ -0,0 +1,77 @@
+// { dg-additional-options "-w" }
+mod intrinsics {
+    extern "rust-intrinsic" {
+        #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
+        pub fn wrapping_add<T>(a: T, b: T) -> T;
+        #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")]
+        pub fn rotate_left<T>(a: T, b: T) -> T;
+        #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")]
+        pub fn rotate_right<T>(a: T, b: T) -> T;
+        #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
+        pub fn offset<T>(ptr: *const T, count: isize) -> *const T;
+    }
+}
+
+mod mem {
+    extern "rust-intrinsic" {
+        #[rustc_const_stable(feature = "const_transmute", since = "1.46.0")]
+        fn transmute<T, U>(_: T) -> U;
+        #[rustc_const_stable(feature = "const_size_of", since = "1.40.0")]
+        fn size_of<T>() -> usize;
+    }
+}
+
+macro_rules! impl_uint {
+    ($($ty:ident = $lang:literal),*) => {
+        $(
+            impl $ty {
+                pub fn wrapping_add(self, rhs: Self) -> Self {
+                    // intrinsics::wrapping_add(self, rhs)
+                    self + rhs
+                }
+
+                pub fn rotate_left(self, n: u32) -> Self {
+                    unsafe {
+                        intrinsics::rotate_left(self, n as Self)
+                    }
+                }
+
+                pub fn rotate_right(self, n: u32) -> Self {
+                    unsafe {
+                        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) }
+                }
+            }
+        )*
+    }
+}
+
+impl_uint!(
+    u8 = "u8",
+    u16 = "u16",
+    u32 = "u32",
+    u64 = "u64",
+    usize = "usize"
+);
diff --git a/gcc/testsuite/rust/compile/torture/issue-1434.rs b/gcc/testsuite/rust/compile/torture/issue-1434.rs
new file mode 100644
index 00000000000..dc000e942e6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/issue-1434.rs
@@ -0,0 +1,53 @@
+// { dg-options "-w" }
+const BLOCK_LEN: usize = 64;
+
+const IV: [u32; 8] = [
+    0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19,
+];
+
+struct ChunkState {
+    chaining_value: [u32; 8],
+    chunk_counter: u64,
+    block: [u8; BLOCK_LEN],
+    block_len: u8,
+    blocks_compressed: u8,
+    flags: u32,
+}
+
+impl ChunkState {
+    fn new(key_words: [u32; 8], chunk_counter: u64, flags: u32) -> Self {
+        Self {
+            chaining_value: key_words,
+            chunk_counter,
+            block: [0; BLOCK_LEN],
+            block_len: 0,
+            blocks_compressed: 0,
+            flags,
+        }
+    }
+}
+
+pub struct Hasher {
+    chunk_state: ChunkState,
+    key_words: [u32; 8],
+    cv_stack: [[u32; 8]; 54], // Space for 54 subtree chaining values:
+    cv_stack_len: u8,         // 2^54 * CHUNK_LEN = 2^64
+    flags: u32,
+}
+
+impl Hasher {
+    fn new_internal(key_words: [u32; 8], flags: u32) -> Self {
+        Self {
+            chunk_state: ChunkState::new(key_words, 0, flags),
+            key_words,
+            cv_stack: [[0; 8]; 54],
+            cv_stack_len: 0,
+            flags,
+        }
+    }
+
+    /// Construct a new `Hasher` for the regular hash function.
+    pub fn new() -> Self {
+        Self::new_internal(IV, 0)
+    }
+}
diff --git a/gcc/testsuite/rust/compile/torture/issue-368.rs b/gcc/testsuite/rust/compile/torture/issue-368.rs
new file mode 100644
index 00000000000..18bc9bdc62e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/issue-368.rs
@@ -0,0 +1,9 @@
+struct S;
+
+fn foo<S>(s: S) -> S {
+    s
+}
+
+fn main() {
+    let _s: S = foo(S);
+}
diff --git a/gcc/testsuite/rust/compile/torture/issue-808.rs b/gcc/testsuite/rust/compile/torture/issue-808.rs
new file mode 100644
index 00000000000..2e5a81fe516
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/issue-808.rs
@@ -0,0 +1,20 @@
+pub trait Foo {
+    type Target;
+
+    fn bar(&self) -> &Self::Target;
+}
+
+impl<T> Foo for &T {
+    type Target = T;
+
+    fn bar(&self) -> &T {
+        *self
+    }
+}
+
+pub fn main() {
+    let a: i32 = 123;
+    let b: &i32 = &a;
+
+    b.bar();
+}
diff --git a/gcc/testsuite/rust/compile/torture/issue-862.rs b/gcc/testsuite/rust/compile/torture/issue-862.rs
new file mode 100644
index 00000000000..c1a4609ba86
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/issue-862.rs
@@ -0,0 +1,74 @@
+// { dg-additional-options "-w" }
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[lang = "deref"]
+pub trait Deref {
+    type Target;
+
+    fn deref(&self) -> &Self::Target;
+}
+
+impl<T> Deref for &T {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        unsafe {
+            let a = "imm_deref\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        *self
+    }
+}
+
+impl<T> Deref for &mut T {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        unsafe {
+            let a = "mut_deref\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        *self
+    }
+}
+
+struct Foo<T>(T);
+impl<T> Deref for Foo<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        unsafe {
+            let a = "foo_deref\n\0";
+            let b = a as *const str;
+            let c = b as *const i8;
+
+            printf(c);
+        }
+
+        &self.0
+    }
+}
+
+struct Bar(i32);
+impl Bar {
+    fn cake(self) -> i32 {
+        self.0 + 1
+    }
+}
+
+pub fn main() {
+    let foo: Foo<Bar> = Foo(Bar(123));
+    let bar: Bar = *foo;
+
+    let cake_result: i32 = foo.cake();
+}
diff --git a/gcc/testsuite/rust/compile/torture/issue-893-2.rs b/gcc/testsuite/rust/compile/torture/issue-893-2.rs
new file mode 100644
index 00000000000..88a865d66dc
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/issue-893-2.rs
@@ -0,0 +1,35 @@
+// { dg-additional-options "-w" }
+struct Foo<T>(T);
+impl<T> Foo<T> {
+    fn new<Y>(a: T, b: Y) -> Self {
+        Self(a)
+    }
+}
+
+struct Bar<T>(T);
+impl Bar<i32> {
+    fn baz(self) {}
+
+    fn test() -> i32 {
+        123
+    }
+}
+
+struct Baz<A, B>(A, B);
+impl Baz<i32, f32> {
+    fn test<X>(a: X) -> X {
+        a
+    }
+}
+
+pub fn main() {
+    let a = Foo::<i32>::new::<f32>(123, 456f32);
+    let b = Foo::new::<f32>(123, 456f32);
+
+    let c = Bar::<i32>(123);
+    let d = Bar::baz(c);
+
+    let e = Bar::test();
+
+    let f = Baz::test::<bool>(true);
+}
diff --git a/gcc/testsuite/rust/compile/torture/issue-893.rs b/gcc/testsuite/rust/compile/torture/issue-893.rs
new file mode 100644
index 00000000000..d8245f3e0d8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/issue-893.rs
@@ -0,0 +1,11 @@
+// { dg-additional-options "-w" }
+struct Foo<T>(T);
+impl<T> Foo<T> {
+    fn new<Y>(a: T, b: Y) -> Self {
+        Self(a)
+    }
+}
+
+pub fn test() {
+    let a = Foo::<i32>::new::<f32>(123, 456f32);
+}
diff --git a/gcc/testsuite/rust/compile/torture/lazybooleanexpr_function.rs b/gcc/testsuite/rust/compile/torture/lazybooleanexpr_function.rs
new file mode 100644
index 00000000000..1be51274d03
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/lazybooleanexpr_function.rs
@@ -0,0 +1,14 @@
+fn foo() -> bool {
+    return true;
+}
+
+fn bar() -> bool {
+    return false;
+}
+
+
+
+fn main() {
+    let _a = true && foo();
+    let _b = true || bar();
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/torture/lifetime1.rs b/gcc/testsuite/rust/compile/torture/lifetime1.rs
new file mode 100644
index 00000000000..151fd827b5e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/lifetime1.rs
@@ -0,0 +1,7 @@
+fn foo<'a>(t: &'a str) -> &'a str {
+    t
+}
+
+fn main() {
+    foo("hello world");
+}
diff --git a/gcc/testsuite/rust/compile/torture/literals1.rs b/gcc/testsuite/rust/compile/torture/literals1.rs
new file mode 100644
index 00000000000..cf021e295d2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/literals1.rs
@@ -0,0 +1,11 @@
+// { dg-prune-output "warning: unused name" } as there are many of these expected.
+
+fn main() {
+    let hex: i32 = 0xFF;
+    let binary: i32 = 0b11110000;
+    let oct: i32 = 0o70;
+
+    let hex_u8: u8 = 0xFF_u8;
+    let bin_u16: u16 = 0b1111000011110000_u16;
+    let oct: u32 = 0o70_u32;
+}
diff --git a/gcc/testsuite/rust/compile/torture/loop1.rs b/gcc/testsuite/rust/compile/torture/loop1.rs
new file mode 100644
index 00000000000..a8ee2f59bb8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/loop1.rs
@@ -0,0 +1,10 @@
+fn main() {
+    let mut a = 1;
+    let mut b = 1;
+
+    loop {
+        let c = a + b;
+        a = b;
+        b = c;
+    }
+}
diff --git a/gcc/testsuite/rust/compile/torture/loop2.rs b/gcc/testsuite/rust/compile/torture/loop2.rs
new file mode 100644
index 00000000000..3de3ea81947
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/loop2.rs
@@ -0,0 +1,14 @@
+fn main() {
+    let mut a = 1;
+    let mut b = 1;
+
+    // first number in Fibonacci sequence over 10:
+    loop {
+        if b > 10 {
+            break;
+        }
+        let c = a + b;
+        a = b;
+        b = c;
+    }
+}
diff --git a/gcc/testsuite/rust/compile/torture/loop3.rs b/gcc/testsuite/rust/compile/torture/loop3.rs
new file mode 100644
index 00000000000..76fadfb4337
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/loop3.rs
@@ -0,0 +1,14 @@
+fn main() {
+    let mut a = 1;
+    let mut b = 1;
+
+    // first number in Fibonacci sequence over 10:
+    loop {
+        if b > 10 {
+            return;
+        }
+        let c = a + b;
+        a = b;
+        b = c;
+    }
+}
diff --git a/gcc/testsuite/rust/compile/torture/loop4.rs b/gcc/testsuite/rust/compile/torture/loop4.rs
new file mode 100644
index 00000000000..f7b59357aeb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/loop4.rs
@@ -0,0 +1,7 @@
+fn main() {
+    'outer: loop {
+        'inner: loop {
+            break 'outer;
+        }
+    }
+}
diff --git a/gcc/testsuite/rust/compile/torture/loop5.rs b/gcc/testsuite/rust/compile/torture/loop5.rs
new file mode 100644
index 00000000000..4004cd30b7b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/loop5.rs
@@ -0,0 +1,14 @@
+fn main() {
+    let mut a = 1;
+    let mut b = 1;
+
+    // first number in Fibonacci sequence over 10:
+    let _fib = loop {
+        if b > 10 {
+            break b;
+        }
+        let c = a + b;
+        a = b;
+        b = c;
+    };
+}
diff --git a/gcc/testsuite/rust/compile/torture/loop6.rs b/gcc/testsuite/rust/compile/torture/loop6.rs
new file mode 100644
index 00000000000..ecd3ad4fd81
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/loop6.rs
@@ -0,0 +1,11 @@
+fn main() {
+    let mut a = 1;
+    let mut b = 1;
+
+    let mut c;
+    while b > 10 {
+        c = a + b;
+        a = b;
+        b = c;
+    }
+}
diff --git a/gcc/testsuite/rust/compile/torture/loop7.rs b/gcc/testsuite/rust/compile/torture/loop7.rs
new file mode 100644
index 00000000000..0cd844592b6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/loop7.rs
@@ -0,0 +1,13 @@
+fn main() {
+    let mut a = 1;
+    let mut b = 1;
+
+    let _fib = loop {
+        if (a % 2 == 0) {
+            continue;
+        }
+        let c = a + b;
+        a = b;
+        b = c;
+    };
+}
diff --git a/gcc/testsuite/rust/compile/torture/macro-issue1403.rs b/gcc/testsuite/rust/compile/torture/macro-issue1403.rs
new file mode 100644
index 00000000000..7fe6c51053c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/macro-issue1403.rs
@@ -0,0 +1,23 @@
+macro_rules! stmt {
+    ($s:stmt) => {
+        $s
+    };
+    ($s:stmt, $($ss:stmt),*) => {
+        $s;
+        stmt!($($ss),*);
+    };
+}
+
+fn main() {
+    stmt!(
+        struct S;
+    );
+    stmt!(
+        struct A;,
+        struct B;,
+        struct C;,
+        struct D;,
+        struct E;
+    );
+}
+
diff --git a/gcc/testsuite/rust/compile/torture/macro-issue1426.rs b/gcc/testsuite/rust/compile/torture/macro-issue1426.rs
new file mode 100644
index 00000000000..1b558cfa83d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/macro-issue1426.rs
@@ -0,0 +1,32 @@
+// { dg-additional-options -fdump-tree-ccp1-raw }
+
+macro_rules! stmt {
+    ($s:stmt) => {
+        $s
+    };
+    ($s:stmt, $($ss:stmt),*) => {
+        $s;
+        stmt!($($ss),*);
+    };
+}
+
+pub fn test() -> i32 {
+    stmt!(
+        let a = 1
+	// { dg-warning {unused name 'a'} {} { target *-*-* } .-1 }
+    );
+    stmt!(
+        let b = 2,
+        let c = 3,
+        let d = 4,
+        let e = 5,
+        let f = b + c + d + e
+    );
+    f
+    // { dg-final { scan-tree-dump-times {gimple_return <14>} 1 ccp1 { target __OPTIMIZE__ } } }
+}
+
+fn main() {
+    let _ = test();
+}
+
diff --git a/gcc/testsuite/rust/compile/torture/macro_as_expr.rs b/gcc/testsuite/rust/compile/torture/macro_as_expr.rs
new file mode 100644
index 00000000000..b0084e7b466
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/macro_as_expr.rs
@@ -0,0 +1,14 @@
+// { dg-additional-options "-w" }
+
+macro_rules! add {
+    ($a:expr) => { $a };
+    ($a:expr, $($b:expr),+) => { $a + add!($($b),*) }
+}
+
+fn main() -> i32 {
+    if add!(add!(1, 2)) > add!(5) {
+        add!(1, add!(2, 3), add!(4))
+    } else {
+        add!(5, add!(6, 7), add!(8), 9) + 10
+    }
+}
diff --git a/gcc/testsuite/rust/compile/torture/match1.rs b/gcc/testsuite/rust/compile/torture/match1.rs
new file mode 100644
index 00000000000..916b11a3194
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/match1.rs
@@ -0,0 +1,16 @@
+// { dg-additional-options "-w" }
+enum Foo {
+    A,
+    B,
+    C(char),
+    D { x: i64, y: i64 },
+}
+
+fn inspect(f: Foo) {
+    match f {
+        Foo::A => {}
+        Foo::B => {}
+        Foo::C(x) => {}
+        Foo::D { x, y } => {}
+    }
+}
diff --git a/gcc/testsuite/rust/compile/torture/methods1.rs b/gcc/testsuite/rust/compile/torture/methods1.rs
new file mode 100644
index 00000000000..a8e384dabea
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/methods1.rs
@@ -0,0 +1,41 @@
+struct Point {
+    x: f64,
+    y: f64,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+impl Point {
+    fn origin() -> Point {
+        Point { x: 0.0, y: 0.0 }
+    }
+
+    fn new(x: f64, y: f64) -> Point {
+        Point { x: x, y: y }
+    }
+}
+
+struct Rectangle {
+    p1: Point,
+    p2: Point,
+}
+
+impl Rectangle {
+    fn from(p1: Point, p2: Point) -> Self {
+        Self { p1, p2 }
+    }
+
+    fn sum_x(self) -> f64 {
+        let p1 = self.p1;
+        let p2 = self.p2;
+        p1.x + p2.x
+    }
+}
+
+fn main() {
+    let p1 = Point::origin();
+    let p2 = Point::new(3.0, 4.0);
+    let rect = Rectangle::from(p1, p2);
+
+    let sum = rect.sum_x();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/methods2.rs b/gcc/testsuite/rust/compile/torture/methods2.rs
new file mode 100644
index 00000000000..d63211bdf8a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/methods2.rs
@@ -0,0 +1,43 @@
+struct Point {
+    x: f64,
+    y: f64,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+impl Point {
+    fn origin() -> Point {
+        Point { x: 0.0, y: 0.0 }
+    }
+
+    fn new(x: f64, y: f64) -> Point {
+        Point { x: x, y: y }
+    }
+}
+
+struct Rectangle {
+    p1: Point,
+    p2: Point,
+}
+
+impl Rectangle {
+    fn from(p1: Point, p2: Point) -> Self {
+        Self { p1, p2 }
+    }
+}
+
+fn main() {
+    let p1 = Point::origin();
+    let p2 = Point::new(3.0, 4.0);
+    let rect = Rectangle::from(p1, p2);
+
+    let sum = rect.sum_x();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
+
+impl Rectangle {
+    fn sum_x(self) -> f64 {
+        let p1 = self.p1;
+        let p2 = self.p2;
+        p1.x + p2.x
+    }
+}
diff --git a/gcc/testsuite/rust/compile/torture/methods3.rs b/gcc/testsuite/rust/compile/torture/methods3.rs
new file mode 100644
index 00000000000..55426f4fcf7
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/methods3.rs
@@ -0,0 +1,44 @@
+struct Point {
+    x: f64,
+    y: f64,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+impl Point {
+    fn origin() -> Point {
+        Point { x: 0.0, y: 0.0 }
+    }
+
+    fn new(x: f64, y: f64) -> Point {
+        Point { x: x, y: y }
+    }
+}
+
+struct Rectangle {
+    p1: Point,
+    p2: Point,
+}
+
+impl Rectangle {
+    fn from(p1: Point, p2: Point) -> Self {
+        Self { p1, p2 }
+    }
+
+    fn sum_x(self) -> f64 {
+        let p1 = self.p1;
+        let p2 = self.p2;
+        p1.x + p2.x
+    }
+}
+
+fn main() {
+    let p1 = Point::origin();
+    let p2 = Point::new(3.0, 4.0);
+    let rect = Rectangle::from(p1, p2);
+
+    let sum = rect.sum_x();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    // multiple MethodCallExpr were causing issue #310
+    let sum = rect.sum_x();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/mod-nameresolve.rs b/gcc/testsuite/rust/compile/torture/mod-nameresolve.rs
new file mode 100644
index 00000000000..09a722681b0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/mod-nameresolve.rs
@@ -0,0 +1,5 @@
+mod foo {
+    struct A; // { dg-warning "struct is never constructed" }
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/torture/mod1.rs b/gcc/testsuite/rust/compile/torture/mod1.rs
new file mode 100644
index 00000000000..651678c6a34
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/mod1.rs
@@ -0,0 +1,11 @@
+// This is testing name resolution
+
+mod _foo {
+    struct _A;
+}
+
+mod _bar {
+    mod _barbis {
+        struct _B;
+    }
+}
diff --git a/gcc/testsuite/rust/compile/torture/mod2.rs b/gcc/testsuite/rust/compile/torture/mod2.rs
new file mode 100644
index 00000000000..04722a94bb1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/mod2.rs
@@ -0,0 +1,13 @@
+mod foomod {
+    pub struct Foo {}
+}
+
+impl foomod::Foo {
+    pub fn new() -> Self {
+        foomod::Foo {}
+    }
+}
+
+fn main() {
+    let _a = foomod::Foo::new();
+}
diff --git a/gcc/testsuite/rust/compile/torture/mod3.rs b/gcc/testsuite/rust/compile/torture/mod3.rs
new file mode 100644
index 00000000000..2ace8c064d8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/mod3.rs
@@ -0,0 +1,22 @@
+// { dg-additional-options "-w" }
+mod A {
+    pub mod B {
+        pub mod C {
+            pub struct Foo {
+                pub f: i32,
+            }
+            impl Foo {
+                pub fn new() -> Self {
+                    Foo { f: 23i32 }
+                }
+            }
+        }
+    }
+}
+
+fn main() -> i32 {
+    let a = A::B::C::Foo::new();
+    let b = A::B::C::Foo { f: -23i32 };
+
+    a.f - b.f
+}
diff --git a/gcc/testsuite/rust/compile/torture/modules/mod.rs b/gcc/testsuite/rust/compile/torture/modules/mod.rs
new file mode 100644
index 00000000000..3d65176b6c3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/modules/mod.rs
@@ -0,0 +1,3 @@
+pub fn return_12() -> i32 {
+    12
+}
diff --git a/gcc/testsuite/rust/compile/torture/modules/valid_path.rs b/gcc/testsuite/rust/compile/torture/modules/valid_path.rs
new file mode 100644
index 00000000000..6a1519c3fc4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/modules/valid_path.rs
@@ -0,0 +1 @@
+fn unused() {}
diff --git a/gcc/testsuite/rust/compile/torture/must_use1.rs b/gcc/testsuite/rust/compile/torture/must_use1.rs
new file mode 100644
index 00000000000..95a6657c8c1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/must_use1.rs
@@ -0,0 +1,16 @@
+#[must_use = "TEST 1"]
+fn test1() -> i32 {
+    123
+}
+
+#[must_use = "TEST 2"]
+fn test2() -> i32 {
+    456
+}
+
+fn main() {
+    let _a = test1();
+
+    test2();
+    // { dg-warning "ignoring return value of" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/must_use2.rs b/gcc/testsuite/rust/compile/torture/must_use2.rs
new file mode 100644
index 00000000000..466f7ee7a14
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/must_use2.rs
@@ -0,0 +1,16 @@
+trait A {
+    #[must_use]
+    fn test() -> i32;
+}
+
+struct S;
+impl A for S {
+    fn test() -> i32 {
+        123
+    }
+}
+
+fn main() {
+    S::test();
+    // { dg-warning "ignoring return value of" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/name_resolve1.rs b/gcc/testsuite/rust/compile/torture/name_resolve1.rs
new file mode 100644
index 00000000000..817f48b60ee
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/name_resolve1.rs
@@ -0,0 +1,23 @@
+struct Foo(i32, bool);
+
+impl Foo {
+    fn new(a: i32, b: bool) -> Foo {
+        Foo(a, b)
+    }
+
+    fn test() -> i32 {
+        test()
+    }
+}
+
+fn test() -> i32 {
+    123
+}
+
+fn main() {
+    let a;
+    a = Foo::new(1, true);
+
+    let b;
+    b = Foo::test();
+}
diff --git a/gcc/testsuite/rust/compile/torture/negation_function.rs b/gcc/testsuite/rust/compile/torture/negation_function.rs
new file mode 100644
index 00000000000..b592f9c00ef
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/negation_function.rs
@@ -0,0 +1,7 @@
+fn ret1() -> i32 {
+    return 1;
+}
+
+fn main() {
+    let _a = -ret1();
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/torture/nested_fn1.rs b/gcc/testsuite/rust/compile/torture/nested_fn1.rs
new file mode 100644
index 00000000000..075b5dba8e0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/nested_fn1.rs
@@ -0,0 +1,10 @@
+pub fn main() {
+    let a = 123;
+
+    fn test(x: i32) -> i32 {
+        x + 456
+    }
+
+    let b;
+    b = test(a);
+}
diff --git a/gcc/testsuite/rust/compile/torture/nested_fn2.rs b/gcc/testsuite/rust/compile/torture/nested_fn2.rs
new file mode 100644
index 00000000000..7040c862e75
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/nested_fn2.rs
@@ -0,0 +1,11 @@
+pub fn main() {
+    fn test<T>(x: T) -> T {
+        x
+    }
+
+    let mut a = 123;
+    a = test(a);
+
+    let mut b = 456f32;
+    b = test(b);
+}
diff --git a/gcc/testsuite/rust/compile/torture/nested_struct1.rs b/gcc/testsuite/rust/compile/torture/nested_struct1.rs
new file mode 100644
index 00000000000..2bd5eadd4c4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/nested_struct1.rs
@@ -0,0 +1,20 @@
+struct Point {
+    x: f64,
+    y: f64,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+struct Rectangle {
+    p1: Point,
+    p2: Point,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+fn main() {
+    let p1 = Point { x: 0.0, y: 0.0 };
+    let p2 = Point { x: 2.0, y: 4.0 };
+    let rect = Rectangle { p1, p2 };
+
+    let a = rect.p1.x;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/never_type1.rs b/gcc/testsuite/rust/compile/torture/never_type1.rs
new file mode 100644
index 00000000000..0f15029097d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/never_type1.rs
@@ -0,0 +1,22 @@
+fn foo() -> i32 {
+    let c;
+    let d;
+
+    c = if false {
+        return 1;
+    } else {
+        0.0
+    };
+
+    d = if true {
+        0.0
+    } else {
+        return 1;
+    };
+
+    0
+}
+
+fn main() {
+    foo();
+}
diff --git a/gcc/testsuite/rust/compile/torture/not_shebang.rs b/gcc/testsuite/rust/compile/torture/not_shebang.rs
new file mode 100644
index 00000000000..37e01b65940
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/not_shebang.rs
@@ -0,0 +1,3 @@
+#!
+[allow(unused)]
+fn main () { }
diff --git a/gcc/testsuite/rust/compile/torture/not_shebang_block_comment.rs b/gcc/testsuite/rust/compile/torture/not_shebang_block_comment.rs
new file mode 100644
index 00000000000..662f6506749
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/not_shebang_block_comment.rs
@@ -0,0 +1 @@
+#!/*/this/is/a/comment*/[allow(unused)] fn main () { }
diff --git a/gcc/testsuite/rust/compile/torture/not_shebang_comment.rs b/gcc/testsuite/rust/compile/torture/not_shebang_comment.rs
new file mode 100644
index 00000000000..273ae4e8e2a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/not_shebang_comment.rs
@@ -0,0 +1,3 @@
+#!//this/is/a/comment
+[allow(unused)]   
+fn main () { }
diff --git a/gcc/testsuite/rust/compile/torture/not_shebang_multiline_comment.rs b/gcc/testsuite/rust/compile/torture/not_shebang_multiline_comment.rs
new file mode 100644
index 00000000000..86800b14cb3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/not_shebang_multiline_comment.rs
@@ -0,0 +1,7 @@
+#!//this/is/a/comment
+
+/* Also a /* nested */
+   multiline // comment
+   with some more whitespace after, but then finally a [, so not a real #! line.  */
+
+[allow(unused)] fn main () { }
diff --git a/gcc/testsuite/rust/compile/torture/not_shebang_spaces.rs b/gcc/testsuite/rust/compile/torture/not_shebang_spaces.rs
new file mode 100644
index 00000000000..6b94a69111a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/not_shebang_spaces.rs
@@ -0,0 +1,6 @@
+#!   
+
+    [allow(unused)]   
+
+        fn main () { }
+    
diff --git a/gcc/testsuite/rust/compile/torture/parameter_usage1.rs b/gcc/testsuite/rust/compile/torture/parameter_usage1.rs
new file mode 100644
index 00000000000..448e9603a94
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/parameter_usage1.rs
@@ -0,0 +1,8 @@
+fn test(a: i32, b: i32) -> i32 {
+    a + b
+}
+
+fn main() {
+    let a = test(1, 4);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/parens1.rs b/gcc/testsuite/rust/compile/torture/parens1.rs
new file mode 100644
index 00000000000..795eb960805
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/parens1.rs
@@ -0,0 +1,5 @@
+fn main() {
+    let a = 123;
+    let b = a + (a * 2);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/pointer1.rs b/gcc/testsuite/rust/compile/torture/pointer1.rs
new file mode 100644
index 00000000000..f283411abe2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/pointer1.rs
@@ -0,0 +1,9 @@
+pub fn main() {
+    let mut num = 2;
+    let r1: *const i32 = &num;
+    let r2 = unsafe { *r1 } + unsafe { *r1 };
+    let r3 = num;
+    num = 4;
+    let r4 = num + unsafe { *r1 } * r3;
+    let _eightteen = r2 + r3 + r4;
+}
diff --git a/gcc/testsuite/rust/compile/torture/primconsts.rs b/gcc/testsuite/rust/compile/torture/primconsts.rs
new file mode 100644
index 00000000000..bcf9456d059
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/primconsts.rs
@@ -0,0 +1,72 @@
+const TRUE: bool = true;
+const FALSE: bool = !TRUE;
+
+const U8ZERO: u8 = 0;
+const U8ONE: u8 = U8ZERO + 1;
+const U16ZERO: u16 = 0;
+const U16ONE: u16 = U16ZERO + 1;
+const U32ZERO: u32 = 0;
+const U32ONE: u32 = U32ZERO + 1;
+const U64ZERO: u64 = 0;
+const U64ONE: u64 = U64ZERO + 1;
+const U128ZERO: u128 = 0;
+const U128ONE: u128 = U128ZERO + 1;
+
+const I8ZERO: i8 = 0;
+const I8ONE: i8 = I8ZERO + 1;
+const I16ZERO: i16 = 0;
+const I16ONE: i16 = I16ZERO + 1;
+const I32ZERO: i32 = 0;
+const I32ONE: i32 = I32ZERO + 1;
+const I64ZERO: i64 = 0;
+const I64ONE: i64 = I64ZERO + 1;
+const I128ZERO: i128 = 0;
+const I128ONE: i128 = I128ZERO + 1;
+
+const F32ZERO: f32 = 0.0;
+const F32ONE: f32 = F32ZERO + 1.0;
+const F64ZERO: f64 = 0.0;
+const F64ONE: f64 = F64ZERO + 1.0;
+
+const USIZEZERO: usize = 0;
+const USIZEONE: usize = USIZEZERO + 1;
+const ISIZEZERO: isize = 0;
+const ISIZEONE: isize = ISIZEZERO + 1;
+
+/* Not yet supported 
+const CHARPI: char = '\u{03C0}';
+const STRHELLO: &str = "Hello World!";
+*/
+
+extern "C" { fn abort (); }
+
+pub fn main ()
+{
+  if TRUE == FALSE { unsafe { abort (); } }
+  if U8ZERO > U8ONE { unsafe { abort (); } }
+  if U16ZERO > U16ONE { unsafe { abort (); } }
+  if U32ZERO > U32ONE { unsafe { abort (); } }
+  if U64ZERO > U64ONE { unsafe { abort (); } }
+  if U128ZERO > U128ONE { unsafe { abort (); } }
+
+  if I8ONE <= I8ZERO { unsafe { abort (); } }
+  if I16ONE <= I16ZERO { unsafe { abort (); } }
+  if I32ONE <= I32ZERO { unsafe { abort (); } }
+  if I64ONE <= I64ZERO { unsafe { abort (); } }
+  if I128ONE <= I128ZERO { unsafe { abort (); } }
+
+  if F32ZERO + F32ONE != F32ONE { unsafe { abort (); } }
+  if F64ZERO + F64ONE != F64ONE { unsafe { abort (); } }
+
+  if USIZEZERO + USIZEONE - USIZEONE + USIZEZERO != USIZEZERO
+    {
+      unsafe { abort (); }
+    }
+  if ISIZEZERO + ISIZEONE - ISIZEONE + ISIZEZERO != ISIZEZERO
+    {
+      unsafe { abort (); }
+    }
+
+ // if CHARPI != '\u{03c0}'  { unsafe { abort (); } }
+ // if STRHELLO != "Hello World!" { unsafe { abort (); } }
+}
diff --git a/gcc/testsuite/rust/compile/torture/prims_struct_eq.rs b/gcc/testsuite/rust/compile/torture/prims_struct_eq.rs
new file mode 100644
index 00000000000..81ab7424627
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/prims_struct_eq.rs
@@ -0,0 +1,91 @@
+extern "C"
+{
+  fn abort ();
+}
+
+struct Prims
+{
+  b1: bool,
+  b2: bool,
+  b3: bool,
+  b4: bool,
+  c1: char,
+  c2: char,
+  u81: u8,
+  u82: u8,
+  u83: u8,
+  u84: u8,
+  i81: i8,
+  i82: i8,
+  i83: i8,
+  i84: i8,
+  u161: u16,
+  u162: u16,
+  i161: i16,
+  i162: i16,
+  u321: u32,
+  u322: u32,
+  i321: i32,
+  i322: i32,
+  u641: u64,
+  i641: i64,
+  u1281: u128,
+  i1281: i128,
+  usize1: usize,
+  isize1: isize,
+}
+
+fn prims_eq (p1: Prims, p2: Prims) -> bool
+{
+  return p1.b1 == p2.b1
+         && p1.b2 == p2.b2
+         && p1.b3 == p2.b3
+         && p1.b4 == p2.b4
+         && p1.c1 == p2.c1
+         && p1.c2 == p2.c2
+         && p1.u81 == p2.u81
+         && p1.u82 == p2.u82
+         && p1.u83 == p2.u83
+         && p1.u84 == p2.u84
+         && p1.i81 == p2.i81
+         && p1.i82 == p2.i82
+         && p1.i83 == p2.i83
+         && p1.i84 == p2.i84
+         && p1.u161 == p2.u161
+         && p1.u162 == p2.u162
+         && p1.i161 == p2.i161
+         && p1.i162 == p2.i162
+         && p1.u321 == p2.u321
+         && p1.u322 == p2.u322
+         && p1.i321 == p2.i321
+         && p1.i322 == p2.i322
+         && p1.u641 == p2.u641
+         && p1.i641 == p2.i641
+         && p1.u1281 == p2.u1281
+         && p1.i1281 == p2.i1281
+         && p1.usize1 == p2.usize1
+         && p1.isize1 == p2.isize1;
+}
+
+pub fn main ()
+{
+  let p1 = Prims { b1: true, b2: false, b3: false, b4: true,
+                   c1: 'a', c2: 'b',
+                   u81: 1, u82: 2, u83: 3, u84: 4,
+                   i81: -1, i82: -2, i83: -3, i84: -4,
+                   u161: 1, u162: 2,
+                   i161: -1, i162: -2,
+                   u321: 1, u322: 2,
+                   i321: -1, i322: -2,
+                   u641: 1,
+                   i641: -1,
+                   u1281: 1,
+                   i1281: -1,
+                   usize1: 1,
+                   isize1: -1 };
+  let p2 = Prims { usize1: 1, .. p1 };
+  let p3 = Prims { u1281: 0, .. p2 };
+  let p4 = Prims { i1281: 0, .. p3 };
+  if !prims_eq (p1, p2) { unsafe { abort (); } }
+  if prims_eq (p3, p4) { unsafe { abort (); } }
+}
diff --git a/gcc/testsuite/rust/compile/torture/range-lang-item1.rs b/gcc/testsuite/rust/compile/torture/range-lang-item1.rs
new file mode 100644
index 00000000000..86946162276
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/range-lang-item1.rs
@@ -0,0 +1,32 @@
+// { dg-additional-options "-w" }
+#[lang = "RangeFull"]
+pub struct RangeFull;
+
+#[lang = "Range"]
+pub struct Range<Idx> {
+    pub start: Idx,
+    pub end: Idx,
+}
+
+#[lang = "RangeFrom"]
+pub struct RangeFrom<Idx> {
+    pub start: Idx,
+}
+
+#[lang = "RangeTo"]
+pub struct RangeTo<Idx> {
+    pub end: Idx,
+}
+
+#[lang = "RangeInclusive"]
+pub struct RangeInclusive<Idx> {
+    pub start: Idx,
+    pub end: Idx,
+}
+
+fn test() {
+    let a = 1..2; // range
+    let b = 1..; // range from
+    let c = ..3; // range to
+    let d = 0..=2; // range inclusive
+}
diff --git a/gcc/testsuite/rust/compile/torture/raw_identifiers.rs b/gcc/testsuite/rust/compile/torture/raw_identifiers.rs
new file mode 100644
index 00000000000..8746f337048
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/raw_identifiers.rs
@@ -0,0 +1,3 @@
+pub fn square(num: i32) -> i32 { /* { dg-warning "used" } */
+    r#num * num
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/torture/raw_identifiers_keywords.rs b/gcc/testsuite/rust/compile/torture/raw_identifiers_keywords.rs
new file mode 100644
index 00000000000..c9aa3cf4938
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/raw_identifiers_keywords.rs
@@ -0,0 +1,3 @@
+pub fn plus(r#break: i32, r#unsafe: i32) -> i32 { /* { dg-warning "used" } */
+    r#break + r#unsafe
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/torture/recursive_fn1.rs b/gcc/testsuite/rust/compile/torture/recursive_fn1.rs
new file mode 100644
index 00000000000..e13b41f70bd
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/recursive_fn1.rs
@@ -0,0 +1,12 @@
+fn gcd(x: i32, y: i32) -> i32 {
+    if y == 0 {
+        x
+    } else {
+        gcd(y, x % y)
+    }
+}
+
+fn main() {
+    let a = gcd(100, 5);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/return_function.rs b/gcc/testsuite/rust/compile/torture/return_function.rs
new file mode 100644
index 00000000000..084adaf7f24
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/return_function.rs
@@ -0,0 +1,5 @@
+fn foo() {}
+
+fn main() {
+    return foo();
+}
diff --git a/gcc/testsuite/rust/compile/torture/scoping1.rs b/gcc/testsuite/rust/compile/torture/scoping1.rs
new file mode 100644
index 00000000000..8bc8ede5f7c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/scoping1.rs
@@ -0,0 +1,11 @@
+fn main() {
+    let x = 1;
+    {
+        let mut x = true;
+        {
+            x = false;
+        }
+    }
+    let x = x + 1;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/self_type1.rs b/gcc/testsuite/rust/compile/torture/self_type1.rs
new file mode 100644
index 00000000000..373d6dd5a60
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/self_type1.rs
@@ -0,0 +1,12 @@
+struct Foo(i32, bool);
+
+impl Foo {
+    fn new(a: i32, b: bool) -> Self {
+        Self(a, b)
+    }
+}
+
+fn main() {
+    let a;
+    a = Foo::new(1, true);
+}
diff --git a/gcc/testsuite/rust/compile/torture/shadow1.rs b/gcc/testsuite/rust/compile/torture/shadow1.rs
new file mode 100644
index 00000000000..b60e7936de9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/shadow1.rs
@@ -0,0 +1,6 @@
+fn main() {
+    let mut x = 5;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let mut x;
+    x = true;
+}
diff --git a/gcc/testsuite/rust/compile/torture/shadow2.rs b/gcc/testsuite/rust/compile/torture/shadow2.rs
new file mode 100644
index 00000000000..161dc380a07
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/shadow2.rs
@@ -0,0 +1,5 @@
+fn main() {
+    let x = 1;
+    let x = x + 1;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/shebang.rs b/gcc/testsuite/rust/compile/torture/shebang.rs
new file mode 100755
index 00000000000..1c8b9c9a955
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/shebang.rs
@@ -0,0 +1,3 @@
+#!/usr/bin/env cat 
+
+fn main () { }
diff --git a/gcc/testsuite/rust/compile/torture/shebang_plus_attr.rs b/gcc/testsuite/rust/compile/torture/shebang_plus_attr.rs
new file mode 100755
index 00000000000..075bc6cf594
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/shebang_plus_attr.rs
@@ -0,0 +1,3 @@
+#!/usr/bin/env cat 
+#![allow(unused)]
+fn main () { }
diff --git a/gcc/testsuite/rust/compile/torture/shebang_plus_attr2.rs b/gcc/testsuite/rust/compile/torture/shebang_plus_attr2.rs
new file mode 100755
index 00000000000..ece8a52381c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/shebang_plus_attr2.rs
@@ -0,0 +1,3 @@
+#!//usr/bin/env cat 
+#![allow(unused)]
+fn main () { }
diff --git a/gcc/testsuite/rust/compile/torture/static_function.rs b/gcc/testsuite/rust/compile/torture/static_function.rs
new file mode 100644
index 00000000000..8e3a3795023
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/static_function.rs
@@ -0,0 +1,8 @@
+fn test(x: i32) -> i32 {
+    return x + 1;
+}
+
+fn main() {
+    let call_test = test(1);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/static_var1.rs b/gcc/testsuite/rust/compile/torture/static_var1.rs
new file mode 100644
index 00000000000..5be0e75ce72
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/static_var1.rs
@@ -0,0 +1,6 @@
+static x:i32 = 3;
+
+fn main() {
+    let y = x +1;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/stmt_with_block1.rs b/gcc/testsuite/rust/compile/torture/stmt_with_block1.rs
new file mode 100644
index 00000000000..b6aa56cc2e6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/stmt_with_block1.rs
@@ -0,0 +1,13 @@
+fn test(x: i32) -> i32 {
+    if x > 1 { 1 } else { 2 };
+    if x > 1 { 1; } else { 2; }
+
+    { 3; }
+    { 3 };
+
+    { 3 }
+}
+
+fn main() {
+    let a = test(0); // { dg-warning "unused name" }
+}
diff --git a/gcc/testsuite/rust/compile/torture/str1.rs b/gcc/testsuite/rust/compile/torture/str1.rs
new file mode 100644
index 00000000000..088827853d8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/str1.rs
@@ -0,0 +1,7 @@
+fn main() {
+    let a;
+    a = "hello world infer";
+
+    let b: &str;
+    b = "hello world specified";
+}
diff --git a/gcc/testsuite/rust/compile/torture/struct_access1.rs b/gcc/testsuite/rust/compile/torture/struct_access1.rs
new file mode 100644
index 00000000000..ec85d289fb5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/struct_access1.rs
@@ -0,0 +1,12 @@
+struct Foo {
+    one: i32,
+    two: i32,
+}
+
+fn main() {
+    let struct_test = Foo { one: 1, two: 2 };
+    let a = struct_test.one;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let b = struct_test.two;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/struct_base_init_1.rs b/gcc/testsuite/rust/compile/torture/struct_base_init_1.rs
new file mode 100644
index 00000000000..ee00c2c468b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/struct_base_init_1.rs
@@ -0,0 +1,13 @@
+struct Foo {
+    a: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+    b: i32,
+}
+
+fn foo() -> Foo {
+    Foo { a: 42, b: 32 }
+}
+
+fn main() {
+    let _f = Foo { a: 10, ..foo() };
+}
diff --git a/gcc/testsuite/rust/compile/torture/struct_decl.rs b/gcc/testsuite/rust/compile/torture/struct_decl.rs
new file mode 100644
index 00000000000..9e8ea6b100b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/struct_decl.rs
@@ -0,0 +1,14 @@
+// { dg-additional-options "-fdump-tree-gimple -frust-crate=example" }
+
+struct Foo {
+    a: u16,
+    // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+    b: u8,
+    // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+fn main() {
+    let my_foo = Foo { a: 1, b: 2 };
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    // { dg-final { scan-tree-dump-times {(?n)const struct example::Foo my_foo;$} 1 gimple } }
+}
diff --git a/gcc/testsuite/rust/compile/torture/struct_init.rs b/gcc/testsuite/rust/compile/torture/struct_init.rs
new file mode 100644
index 00000000000..1926f73b21d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/struct_init.rs
@@ -0,0 +1,11 @@
+struct Foo {
+    one: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+    two: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+fn main() {
+    let struct_test = Foo { one: 1, two: 2 };
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/struct_init_10.rs b/gcc/testsuite/rust/compile/torture/struct_init_10.rs
new file mode 100644
index 00000000000..7fbceb03974
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/struct_init_10.rs
@@ -0,0 +1,9 @@
+fn main() {
+    struct foo {
+        a: i32,
+        b: f32,
+    };
+
+    let a;
+    a = foo { a: 123, b: 456f32 };
+}
diff --git a/gcc/testsuite/rust/compile/torture/struct_init_11.rs b/gcc/testsuite/rust/compile/torture/struct_init_11.rs
new file mode 100644
index 00000000000..16a2f072566
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/struct_init_11.rs
@@ -0,0 +1,34 @@
+pub fn main() {
+    struct O(i32);
+    struct T(i32, i32);
+    struct M(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32);
+
+    // tuples
+    let z = ();
+    let o = (0,);
+    let f = o.0;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let t = (0, 1);
+    let s = t.1;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let m = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+    let l = m.10;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    // tuple structs
+    let so = O(0);
+    let sf = so.0;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let st = T(0, 1);
+    let fs = st.1;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let sm = M(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+    let sl = sm.10;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    z
+}
diff --git a/gcc/testsuite/rust/compile/torture/struct_init_2.rs b/gcc/testsuite/rust/compile/torture/struct_init_2.rs
new file mode 100644
index 00000000000..d7040d3d96d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/struct_init_2.rs
@@ -0,0 +1,6 @@
+struct Foo(f32, f32);
+
+fn main() {
+    let a = Foo { 0: 10.0, 1: 20.0 };
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/struct_init_3.rs b/gcc/testsuite/rust/compile/torture/struct_init_3.rs
new file mode 100644
index 00000000000..1398f8e7b86
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/struct_init_3.rs
@@ -0,0 +1,13 @@
+struct Foo {
+    a: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+    b: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+fn main() {
+    let a = 1;
+    let b = 2;
+    let c = Foo { a, b };
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/struct_init_4.rs b/gcc/testsuite/rust/compile/torture/struct_init_4.rs
new file mode 100644
index 00000000000..2b2746aba7a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/struct_init_4.rs
@@ -0,0 +1,13 @@
+struct Foo {
+    a: i32,
+    // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+    b: i32,
+    // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+fn main() {
+    let a = Foo { a: 1, b: 2 };
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let b = Foo { a: 3, b: 4, ..a };
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/struct_init_5.rs b/gcc/testsuite/rust/compile/torture/struct_init_5.rs
new file mode 100644
index 00000000000..891f64540fe
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/struct_init_5.rs
@@ -0,0 +1,10 @@
+struct Foo {
+    a: i32,
+    b: i32,
+}
+
+fn main() {
+    let a = Foo { a: 1, b: 2 };
+    let b = Foo { ..a };
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/struct_init_6.rs b/gcc/testsuite/rust/compile/torture/struct_init_6.rs
new file mode 100644
index 00000000000..9fc52ed5c50
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/struct_init_6.rs
@@ -0,0 +1,11 @@
+struct Foo {
+    a: i32,
+    // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+    b: i32,
+}
+
+fn main() {
+    let a = Foo { a: 1, b: 2 };
+    let b = Foo { a: 1, ..a };
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/struct_init_7.rs b/gcc/testsuite/rust/compile/torture/struct_init_7.rs
new file mode 100644
index 00000000000..36dc00aca60
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/struct_init_7.rs
@@ -0,0 +1,11 @@
+struct Foo {
+    a: i32,
+    b: f32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+fn main() {
+    let c = Foo { a: 1, b: 2f32 };
+    let b = Foo { b: 4f32, ..c };
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/struct_init_8.rs b/gcc/testsuite/rust/compile/torture/struct_init_8.rs
new file mode 100644
index 00000000000..411ff7d1c6f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/struct_init_8.rs
@@ -0,0 +1,7 @@
+struct Foo(f32, i32);
+
+fn main() {
+    let a = Foo { 1: 1, 0: 2f32 };
+    let b = Foo { ..a };
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/struct_init_9.rs b/gcc/testsuite/rust/compile/torture/struct_init_9.rs
new file mode 100644
index 00000000000..2daa078d5b3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/struct_init_9.rs
@@ -0,0 +1,6 @@
+fn main() {
+    struct foo(i32, f32);
+
+    let a;
+    a = foo(123, 456f32);
+}
diff --git a/gcc/testsuite/rust/compile/torture/top_attr.rs b/gcc/testsuite/rust/compile/torture/top_attr.rs
new file mode 100644
index 00000000000..0671369cb12
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/top_attr.rs
@@ -0,0 +1,5 @@
+#![crate_name = "name"]
+
+
+#[allow(dead_code)]
+fn main() {}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/torture/traits1.rs b/gcc/testsuite/rust/compile/torture/traits1.rs
new file mode 100644
index 00000000000..90357738a81
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits1.rs
@@ -0,0 +1,16 @@
+trait Foo {
+    fn bar() -> i32;
+}
+
+struct Test(i32, f32);
+
+impl Foo for Test {
+    fn bar() -> i32 {
+        123
+    }
+}
+
+fn main() {
+    let a: i32;
+    a = Test::bar();
+}
diff --git a/gcc/testsuite/rust/compile/torture/traits10.rs b/gcc/testsuite/rust/compile/torture/traits10.rs
new file mode 100644
index 00000000000..a02927007b3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits10.rs
@@ -0,0 +1,30 @@
+trait Foo // where
+//     Self: Sized,
+{
+    fn get(self) -> i32;
+
+    fn test(self) -> i32 {
+        self.get()
+    }
+}
+
+struct Bar(i32);
+impl Foo for Bar {
+    fn get(self) -> i32 {
+        self.0
+    }
+}
+
+fn main() {
+    let a;
+    a = Bar(123);
+
+    let b;
+    b = Bar::get(a);
+
+    let a;
+    a = Bar(123);
+
+    let b;
+    b = a.test();
+}
diff --git a/gcc/testsuite/rust/compile/torture/traits11.rs b/gcc/testsuite/rust/compile/torture/traits11.rs
new file mode 100644
index 00000000000..41c82f01b6d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits11.rs
@@ -0,0 +1,31 @@
+trait Foo {
+    type A;
+
+    fn test(a: Self::A) -> Self::A {
+        a
+    }
+}
+
+struct Bar(i32);
+impl Foo for Bar {
+    type A = i32;
+}
+
+struct Baz(f32);
+impl Foo for Baz {
+    type A = f32;
+}
+
+fn main() {
+    let a;
+    a = Bar(123);
+
+    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/torture/traits12.rs b/gcc/testsuite/rust/compile/torture/traits12.rs
new file mode 100644
index 00000000000..a55b965baf0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits12.rs
@@ -0,0 +1,29 @@
+trait Foo {
+    type A;
+
+    fn test(a: Self::A) -> Self::A {
+        a
+    }
+}
+
+struct Bar(i32);
+// { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+
+impl Foo for Bar {
+    type A = i32;
+}
+
+struct Baz(f32);
+// { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+
+impl Foo for Baz {
+    type A = f32;
+}
+
+fn main() {
+    let a: <Baz as Foo>::A;
+    a = 123f32;
+
+    let b;
+    b = <Baz as Foo>::test(a);
+}
diff --git a/gcc/testsuite/rust/compile/torture/traits13.rs b/gcc/testsuite/rust/compile/torture/traits13.rs
new file mode 100644
index 00000000000..326f0390756
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits13.rs
@@ -0,0 +1,17 @@
+trait Trait {
+    const FOO: usize;
+    type Target;
+}
+
+struct S;
+// { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+
+impl Trait for S {
+    const FOO: usize = 0;
+    type Target = usize;
+}
+
+fn main() {
+    let a: <S as Trait>::Target;
+    a = <S as Trait>::FOO;
+}
diff --git a/gcc/testsuite/rust/compile/torture/traits14.rs b/gcc/testsuite/rust/compile/torture/traits14.rs
new file mode 100644
index 00000000000..8bca0d5c1f6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits14.rs
@@ -0,0 +1,23 @@
+trait Foo<T> {
+    type A;
+
+    fn test(a: T) -> T {
+        a
+    }
+}
+
+struct Bar<T>(T);
+impl<T> Foo<T> for Bar<T> {
+    type A = T;
+}
+
+pub fn main() {
+    let a;
+    a = Bar(123);
+
+    let b: <Bar<i32> as Foo<i32>>::A;
+    b = 456;
+
+    let c: <Bar<i32> as Foo<i32>>::A;
+    c = <Bar<i32> as Foo<i32>>::test(a.0);
+}
diff --git a/gcc/testsuite/rust/compile/torture/traits15.rs b/gcc/testsuite/rust/compile/torture/traits15.rs
new file mode 100644
index 00000000000..c8c40b78b45
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits15.rs
@@ -0,0 +1,23 @@
+trait Foo<T> {
+    type A;
+
+    fn test(a: T, b: Self::A) -> (T, Self::A) {
+        (a, b)
+    }
+}
+
+struct Bar<T>(T);
+impl<T> Foo<T> for Bar<T> {
+    type A = T;
+}
+
+pub fn main() {
+    let a;
+    a = Bar(123);
+
+    let b: <Bar<i32> as Foo<i32>>::A;
+    b = 456;
+
+    let c;
+    c = <Bar<i32> as Foo<i32>>::test(a.0, 123);
+}
diff --git a/gcc/testsuite/rust/compile/torture/traits16.rs b/gcc/testsuite/rust/compile/torture/traits16.rs
new file mode 100644
index 00000000000..afc4a86de6d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits16.rs
@@ -0,0 +1,20 @@
+trait A {
+    fn a() -> i32 {
+        123
+    }
+
+    fn b() -> i32 {
+        Self::a() + 456
+    }
+}
+
+struct S;
+impl A for S {}
+
+fn main() {
+    let a;
+    a = S::a();
+
+    let b;
+    b = S::b();
+}
diff --git a/gcc/testsuite/rust/compile/torture/traits17.rs b/gcc/testsuite/rust/compile/torture/traits17.rs
new file mode 100644
index 00000000000..6da8bcb0082
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits17.rs
@@ -0,0 +1,23 @@
+trait A {
+    fn a() -> i32 {
+        123
+    }
+}
+
+trait B: A {
+    fn b() -> i32 {
+        Self::a() + 456
+    }
+}
+
+struct S;
+impl A for S {}
+impl B for S {}
+
+fn main() {
+    let a;
+    a = S::a();
+
+    let b;
+    b = S::b();
+}
diff --git a/gcc/testsuite/rust/compile/torture/traits18.rs b/gcc/testsuite/rust/compile/torture/traits18.rs
new file mode 100644
index 00000000000..63319dd2daa
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits18.rs
@@ -0,0 +1,5 @@
+trait Foo<'a> {}
+
+trait Bar {
+    type Item: for<'a> Foo<'a>;
+}
diff --git a/gcc/testsuite/rust/compile/torture/traits19.rs b/gcc/testsuite/rust/compile/torture/traits19.rs
new file mode 100644
index 00000000000..4412656f535
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits19.rs
@@ -0,0 +1,33 @@
+// { dg-additional-options "-w" }
+trait Get {
+    type Value;
+    fn get(&self) -> &<Self as Get>::Value;
+}
+
+struct Struct {
+    x: isize,
+}
+
+impl Get for Struct {
+    type Value = isize;
+    fn get(&self) -> &isize {
+        &self.x
+    }
+}
+
+trait Grab {
+    type U;
+    fn grab(&self) -> &<Self as Grab>::U;
+}
+
+impl<T: Get> Grab for T {
+    type U = <T as Get>::Value;
+    fn grab(&self) -> &<T as Get>::Value {
+        self.get()
+    }
+}
+
+fn main() {
+    let s = Struct { x: 100 };
+    let a = s.grab();
+}
diff --git a/gcc/testsuite/rust/compile/torture/traits2.rs b/gcc/testsuite/rust/compile/torture/traits2.rs
new file mode 100644
index 00000000000..fc6eb6002e0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits2.rs
@@ -0,0 +1,16 @@
+trait Foo {
+    fn bar() -> i32;
+}
+
+struct Test<T>(T);
+
+impl<T> Foo for Test<T> {
+    fn bar() -> i32 {
+        123
+    }
+}
+
+fn main() {
+    let a: i32;
+    a = Test::<i32>::bar();
+}
diff --git a/gcc/testsuite/rust/compile/torture/traits3.rs b/gcc/testsuite/rust/compile/torture/traits3.rs
new file mode 100644
index 00000000000..deeb81e0946
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits3.rs
@@ -0,0 +1,15 @@
+pub trait Foo {
+    fn Bar(self) -> i32;
+}
+
+struct Baz;
+// { dg-warning "struct is never constructed: .Baz." "" { target *-*-* } .-1 }
+
+impl Foo for Baz {
+    fn Bar(self) -> i32 {
+        // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
+        123
+    }
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/torture/traits4.rs b/gcc/testsuite/rust/compile/torture/traits4.rs
new file mode 100644
index 00000000000..67b012c11f5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits4.rs
@@ -0,0 +1,21 @@
+trait Foo {
+    type A;
+    type B;
+
+    fn new(a: Self::A, b: Self::B) -> Self;
+}
+
+struct Baz(i32, f32);
+
+impl Foo for Baz {
+    type A = i32;
+    type B = f32;
+
+    fn new(a: Self::A, b: Self::B) -> Self {
+        Baz(a, b)
+    }
+}
+
+fn main() {
+    Baz::new(123, 456f32);
+}
diff --git a/gcc/testsuite/rust/compile/torture/traits5.rs b/gcc/testsuite/rust/compile/torture/traits5.rs
new file mode 100644
index 00000000000..445b0658f5c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits5.rs
@@ -0,0 +1,21 @@
+trait Foo {
+    type A;
+    type B;
+
+    fn new(a: Self::A, b: Self::B) -> Self;
+}
+
+struct Baz(i32, f32);
+
+impl Foo for Baz {
+    type A = i32;
+    type B = f32;
+
+    fn new(a: i32, b: f32) -> Self {
+        Baz(a, b)
+    }
+}
+
+fn main() {
+    Baz::new(123, 456f32);
+}
diff --git a/gcc/testsuite/rust/compile/torture/traits6.rs b/gcc/testsuite/rust/compile/torture/traits6.rs
new file mode 100644
index 00000000000..260dde3f465
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits6.rs
@@ -0,0 +1,20 @@
+trait Foo {
+    type A;
+
+    fn baz(a: Self::A) -> Self::A;
+}
+
+struct Bar<T>(T);
+
+impl<T> Foo for Bar<T> {
+    type A = T;
+
+    fn baz(a: Self::A) -> T {
+        a
+    }
+}
+
+fn main() {
+    let a;
+    a = Bar::<i32>::baz(123);
+}
diff --git a/gcc/testsuite/rust/compile/torture/traits7.rs b/gcc/testsuite/rust/compile/torture/traits7.rs
new file mode 100644
index 00000000000..7bc3384ab41
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits7.rs
@@ -0,0 +1,19 @@
+trait Foo {
+    const A: i32;
+
+    fn test(self);
+}
+
+struct Bar;
+impl Foo for Bar {
+    const A: i32 = 123;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    fn test(self) {}
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
+
+fn main() {
+    let a = Bar;
+    a.test();
+}
diff --git a/gcc/testsuite/rust/compile/torture/traits8.rs b/gcc/testsuite/rust/compile/torture/traits8.rs
new file mode 100644
index 00000000000..459032fb4a2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits8.rs
@@ -0,0 +1,21 @@
+trait Foo {
+    fn default() -> i32;
+}
+
+struct Bar(i32);
+// { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+
+impl Foo for Bar {
+    fn default() -> i32 {
+        123
+    }
+}
+
+fn type_bound_test<T: Foo>() -> i32 {
+    T::default()
+}
+
+fn main() {
+    let a;
+    a = type_bound_test::<Bar>();
+}
diff --git a/gcc/testsuite/rust/compile/torture/traits9.rs b/gcc/testsuite/rust/compile/torture/traits9.rs
new file mode 100644
index 00000000000..89e4bf19b0c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/traits9.rs
@@ -0,0 +1,27 @@
+trait Foo {
+    fn default() -> i32;
+    fn get(self) -> i32;
+}
+
+struct Bar(i32);
+impl Foo for Bar {
+    fn default() -> i32 {
+        123
+    }
+
+    fn get(self) -> i32 {
+        self.0
+    }
+}
+
+fn type_bound_test<T: Foo>(a: T) -> i32 {
+    T::default() + a.get()
+}
+
+fn main() {
+    let a;
+    a = Bar(456);
+
+    let b;
+    b = type_bound_test(a);
+}
diff --git a/gcc/testsuite/rust/compile/torture/transmute-size-check-1.rs b/gcc/testsuite/rust/compile/torture/transmute-size-check-1.rs
new file mode 100644
index 00000000000..461a35de8ef
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/transmute-size-check-1.rs
@@ -0,0 +1,11 @@
+mod mem {
+    extern "rust-intrinsic" {
+        fn size_of<T>() -> usize;
+        fn transmute<U, V>(_: U) -> V; // { dg-error "cannot transmute between types of different sizes, or dependently-sized types" }
+    }
+}
+
+fn main() {
+    let a = 123;
+    let _b: [u32; mem::size_of::<i32>()] = unsafe { mem::transmute(a) };
+}
diff --git a/gcc/testsuite/rust/compile/torture/transmute1.rs b/gcc/testsuite/rust/compile/torture/transmute1.rs
new file mode 100644
index 00000000000..af9a55d1b97
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/transmute1.rs
@@ -0,0 +1,11 @@
+mod mem {
+    extern "rust-intrinsic" {
+        fn size_of<T>() -> usize;
+        fn transmute<U, V>(_: U) -> V;
+    }
+}
+
+fn main() {
+    let a = 123;
+    let _b: [u8; mem::size_of::<i32>()] = unsafe { mem::transmute(a) };
+}
diff --git a/gcc/testsuite/rust/compile/torture/tuple1.rs b/gcc/testsuite/rust/compile/torture/tuple1.rs
new file mode 100644
index 00000000000..9e6f613f682
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/tuple1.rs
@@ -0,0 +1,6 @@
+fn main() {
+    let a: (i32, bool) = (123, true);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let b;
+    b = (456, 5f32);
+}
diff --git a/gcc/testsuite/rust/compile/torture/tuple2.rs b/gcc/testsuite/rust/compile/torture/tuple2.rs
new file mode 100644
index 00000000000..ab3d0b8715b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/tuple2.rs
@@ -0,0 +1,5 @@
+fn main() {
+    let a = 123;
+    let b = (a,);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/tuple3.rs b/gcc/testsuite/rust/compile/torture/tuple3.rs
new file mode 100644
index 00000000000..d0fb6fc4429
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/tuple3.rs
@@ -0,0 +1,9 @@
+fn main() {
+    let a = (1, true);
+
+    let b;
+    let c;
+
+    b = a.0;
+    c = a.1;
+}
diff --git a/gcc/testsuite/rust/compile/torture/tuple_enum_variants.rs b/gcc/testsuite/rust/compile/torture/tuple_enum_variants.rs
new file mode 100644
index 00000000000..d953e3d89a1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/tuple_enum_variants.rs
@@ -0,0 +1,23 @@
+enum E {
+    T0(),
+    T1(i32),
+    T2(i32, u32),
+}
+
+/* The following doesn't parse yet...
+fn f(e0: E, e1: E, e2: E) -> (E,E,E,())
+{
+  let e = e0;
+  let f = e1;
+  let g = e2;
+  (e,f,g,())
+}
+
+fn main()
+{
+  let e0 = E::T0();
+  let e1 = E::T1(0);
+  let e2 = E::T2(0,1);
+  f(e0, e1, e2).3
+}
+*/
diff --git a/gcc/testsuite/rust/compile/torture/tuple_field_access.rs b/gcc/testsuite/rust/compile/torture/tuple_field_access.rs
new file mode 100644
index 00000000000..8d1bbe9906c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/tuple_field_access.rs
@@ -0,0 +1,6 @@
+struct Foo(i32, i32);
+
+fn main() {
+    let mut a = Foo(1, 2);
+    a.0 = 22;
+}
diff --git a/gcc/testsuite/rust/compile/torture/tuple_function.rs b/gcc/testsuite/rust/compile/torture/tuple_function.rs
new file mode 100644
index 00000000000..514b586cc09
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/tuple_function.rs
@@ -0,0 +1,6 @@
+fn foo() -> i32 {
+    return 1;
+}
+fn main() {
+    let _a = (foo(), 2);
+}
diff --git a/gcc/testsuite/rust/compile/torture/tuple_index.rs b/gcc/testsuite/rust/compile/torture/tuple_index.rs
new file mode 100644
index 00000000000..f904fae9b5b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/tuple_index.rs
@@ -0,0 +1,32 @@
+fn main()
+{
+  // tuples
+  let z = ();
+
+  let o = (0,);
+  let _f = o.0;
+
+  let t = (0,1);
+  let _s = t.1;
+
+  let m = (0,1,2,3,4,5,6,7,8,9,10);
+  let _l = m.10;
+
+  // tuple structs
+  struct E();
+  let _e = E();
+
+  struct O(i32);
+  let so = O(0);
+  let _sf = so.0;
+
+  struct T(i32,i32);
+  let st = T(0,1);
+  let _fs = st.1;
+
+  struct M(i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,i32);
+  let sm = M(0,1,2,3,4,5,6,7,8,9,10);
+  let _sl = sm.10;
+
+  z
+}
diff --git a/gcc/testsuite/rust/compile/torture/tuple_struct1.rs b/gcc/testsuite/rust/compile/torture/tuple_struct1.rs
new file mode 100644
index 00000000000..0ac19b179a9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/tuple_struct1.rs
@@ -0,0 +1,6 @@
+struct Foo(i32, i32, bool);
+
+fn main() {
+    let a = Foo(1, 2, true);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/tuple_struct2.rs b/gcc/testsuite/rust/compile/torture/tuple_struct2.rs
new file mode 100644
index 00000000000..5e0a76e1de8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/tuple_struct2.rs
@@ -0,0 +1,11 @@
+struct Foo(i32, bool);
+
+fn main() {
+    let a = Foo(1, true);
+
+    let b;
+    let c;
+
+    b = a.0;
+    c = a.1;
+}
diff --git a/gcc/testsuite/rust/compile/torture/tuple_struct_unit.rs b/gcc/testsuite/rust/compile/torture/tuple_struct_unit.rs
new file mode 100644
index 00000000000..cda19d2af0b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/tuple_struct_unit.rs
@@ -0,0 +1,11 @@
+struct E();
+struct T(E,E,());
+
+fn main()
+{
+  let z0 = E();
+  let z1 = E();
+  let t = T(z0,z1,());
+  let z = t.2;
+  z
+}
diff --git a/gcc/testsuite/rust/compile/torture/tuple_struct_unused.rs b/gcc/testsuite/rust/compile/torture/tuple_struct_unused.rs
new file mode 100644
index 00000000000..8da0a50632b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/tuple_struct_unused.rs
@@ -0,0 +1,4 @@
+struct Foo(i32, i32);
+// { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/torture/type-alias1.rs b/gcc/testsuite/rust/compile/torture/type-alias1.rs
new file mode 100644
index 00000000000..78bf0461036
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/type-alias1.rs
@@ -0,0 +1,6 @@
+type TypeAlias = (i32, u32);
+
+fn main() {
+    let a: TypeAlias;
+    a = (123, 456);
+}
diff --git a/gcc/testsuite/rust/compile/torture/type-alias2.rs b/gcc/testsuite/rust/compile/torture/type-alias2.rs
new file mode 100644
index 00000000000..a3e3f4e6851
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/type-alias2.rs
@@ -0,0 +1,8 @@
+type x = u32;
+
+fn main() {
+    let x: x = 1;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let y: x = 2;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/type_infer1.rs b/gcc/testsuite/rust/compile/torture/type_infer1.rs
new file mode 100644
index 00000000000..3fee7282bde
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/type_infer1.rs
@@ -0,0 +1,24 @@
+struct Foo {
+    one: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+    two: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+fn test(x: i32) -> i32 {
+    return x + 1;
+}
+
+fn main() {
+    let logical: bool = true;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let an_integer = 5;
+    let mut default_integer = 7;
+
+    default_integer = 1 + an_integer;
+
+    let call_test = test(1);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let struct_test = Foo { one: 1, two: 2 };
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/type_infer2.rs b/gcc/testsuite/rust/compile/torture/type_infer2.rs
new file mode 100644
index 00000000000..dcddda42729
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/type_infer2.rs
@@ -0,0 +1,9 @@
+fn test(x: i32) -> i32 {
+    return x + 1;
+}
+
+fn main() {
+    let an_integer = 5;
+    let call_test = test(an_integer + 1);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/type_infer3.rs b/gcc/testsuite/rust/compile/torture/type_infer3.rs
new file mode 100644
index 00000000000..303dd3d1f18
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/type_infer3.rs
@@ -0,0 +1,14 @@
+fn test(x: i32) -> i32 {
+    return x + 1;
+}
+
+fn main() {
+    let mut an_integer = 5;
+    an_integer = test(1) + 3;
+
+    let mut x;
+    x = 1;
+
+    let call_test = test(1);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/type_infer4.rs b/gcc/testsuite/rust/compile/torture/type_infer4.rs
new file mode 100644
index 00000000000..77a919f262a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/type_infer4.rs
@@ -0,0 +1,11 @@
+fn main() {
+    let xs: [i32; 5] = [1, 2, 3, 4, 5];
+    let xy = [6, 7, 8];
+
+    let a = xs[0];
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let b = xy[2];
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let mut c;
+    c = xs[0];
+}
diff --git a/gcc/testsuite/rust/compile/torture/type_infer5.rs b/gcc/testsuite/rust/compile/torture/type_infer5.rs
new file mode 100644
index 00000000000..2c2602a161f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/type_infer5.rs
@@ -0,0 +1,13 @@
+struct Foo {
+    a: i32,
+    b: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+fn main() {
+    let a;
+    a = Foo { a: 1, b: 2 };
+
+    let b = a.a;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/type_infer6.rs b/gcc/testsuite/rust/compile/torture/type_infer6.rs
new file mode 100644
index 00000000000..6f5863f0107
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/type_infer6.rs
@@ -0,0 +1,14 @@
+fn test(x: u32) -> u32 {
+    return x + 1;
+}
+
+fn main() {
+    let a;
+    a = 1;
+    let b = test(a);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let c = 1;
+    let d = test(c + 1);
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/unary_operators.rs b/gcc/testsuite/rust/compile/torture/unary_operators.rs
new file mode 100644
index 00000000000..9be729c04e3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/unary_operators.rs
@@ -0,0 +1,8 @@
+// { dg-prune-output "warning: unused name" } as there are many of these expected.
+
+fn main() {
+    let a: i32 = -1;
+    let b: i32 = 3 - -1;
+    let c: bool = !false;
+    let d: i32 = !3;
+}
diff --git a/gcc/testsuite/rust/compile/torture/undended-string-1.rs b/gcc/testsuite/rust/compile/torture/undended-string-1.rs
new file mode 100644
index 00000000000..66f0cd52269
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/undended-string-1.rs
@@ -0,0 +1,5 @@
+// { dg-excess-errors "...." }
+fn main() {
+    // { dg-error "unended string literal" "" { target *-*-* } .+1 }
+    let s = "123
+}
diff --git a/gcc/testsuite/rust/compile/torture/undended-string-2.rs b/gcc/testsuite/rust/compile/torture/undended-string-2.rs
new file mode 100644
index 00000000000..c0f424927c2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/undended-string-2.rs
@@ -0,0 +1,5 @@
+// { dg-excess-errors "...." }
+fn main() {
+    // { dg-error "unended byte string literal" "" { target *-*-* } .+1 }
+    let s = b"123
+}
diff --git a/gcc/testsuite/rust/compile/torture/underscore_id.rs b/gcc/testsuite/rust/compile/torture/underscore_id.rs
new file mode 100644
index 00000000000..2c106c55df9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/underscore_id.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let _unused_but_fine = 12;
+    let unused = 12; // { dg-warning "unused name" }
+}
diff --git a/gcc/testsuite/rust/compile/torture/union.rs b/gcc/testsuite/rust/compile/torture/union.rs
new file mode 100644
index 00000000000..724168817ad
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/union.rs
@@ -0,0 +1,32 @@
+union U
+{
+  f1: u8
+}
+
+union V
+{
+  f1: u8,
+  f2: u16,
+  f3: i32,
+}
+
+struct S
+{
+  f1: U,
+  f2: V
+}
+
+fn main ()
+{
+  let u = U { f1: 16 };
+  let v = V { f2: 365 };
+  let s = S { f1: u, f2: v };
+  let _v125 = unsafe
+    { let mut uv: u64;
+      uv = s.f1.f1 as u64;
+      uv += s.f2.f1 as u64;
+      uv += s.f2.f2 as u64;
+      uv -= s.f2.f3 as u64;
+      uv
+    };
+}
diff --git a/gcc/testsuite/rust/compile/torture/union_union.rs b/gcc/testsuite/rust/compile/torture/union_union.rs
new file mode 100644
index 00000000000..9feb145a692
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/union_union.rs
@@ -0,0 +1,27 @@
+union union
+{
+  union: u32,
+  inion: i32,
+  u8ion: u8,
+  i64on: i64,
+  u64on: u64
+}
+
+pub fn main ()
+{
+  let union = union { union: 2 };
+  let inion = union { inion: -2 };
+  let mut mnion = union { inion: -16 };
+  let m1 = unsafe { mnion.union };
+  unsafe { mnion.union = union.union };
+  let m2 = unsafe { mnion.inion };
+  let u1 = unsafe { union.union };
+  let i1 = unsafe { union.inion };
+  let u2 = unsafe { inion.union };
+  let i2 = unsafe { inion.inion };
+  let _r1 = u2 - u1 - m1;
+  let _r2 = i1 + i2 + m2;
+  let _u8 = unsafe { union.u8ion };
+  let _i64 = unsafe { union.i64on };
+  let _u64 = unsafe { union.u64on };
+}
diff --git a/gcc/testsuite/rust/compile/torture/unit_type1.rs b/gcc/testsuite/rust/compile/torture/unit_type1.rs
new file mode 100644
index 00000000000..d5f73575745
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/unit_type1.rs
@@ -0,0 +1,7 @@
+fn main() {
+    let a: () = ();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+
+    let b;
+    b = ();
+}
diff --git a/gcc/testsuite/rust/compile/torture/unit_type2.rs b/gcc/testsuite/rust/compile/torture/unit_type2.rs
new file mode 100644
index 00000000000..b5f925907d8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/unit_type2.rs
@@ -0,0 +1,8 @@
+fn test(a: ()) -> () {
+    a
+}
+
+fn main() {
+    let a;
+    a = test(());
+}
diff --git a/gcc/testsuite/rust/compile/torture/unit_type3.rs b/gcc/testsuite/rust/compile/torture/unit_type3.rs
new file mode 100644
index 00000000000..d48a691046b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/unit_type3.rs
@@ -0,0 +1,6 @@
+struct S;
+
+fn main() {
+    let s = S;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/unit_type4.rs b/gcc/testsuite/rust/compile/torture/unit_type4.rs
new file mode 100644
index 00000000000..ccbfa21818a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/unit_type4.rs
@@ -0,0 +1,5 @@
+struct S;
+
+fn main() {
+    let _s = S {};
+}
diff --git a/gcc/testsuite/rust/compile/torture/unit_type5.rs b/gcc/testsuite/rust/compile/torture/unit_type5.rs
new file mode 100644
index 00000000000..3c4323aa73c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/unit_type5.rs
@@ -0,0 +1,8 @@
+struct Foo;
+
+fn main() {
+    let a = Foo {};
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let b = Foo;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/unsafe1.rs b/gcc/testsuite/rust/compile/torture/unsafe1.rs
new file mode 100644
index 00000000000..f57ef52b9c0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/unsafe1.rs
@@ -0,0 +1,12 @@
+fn test() -> i32 {
+    unsafe {
+        let a;
+        a = 123;
+        a
+    }
+}
+
+fn main() {
+    let a;
+    a = test();
+}
diff --git a/gcc/testsuite/rust/compile/torture/unsafe2.rs b/gcc/testsuite/rust/compile/torture/unsafe2.rs
new file mode 100644
index 00000000000..0b3aad53a44
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/unsafe2.rs
@@ -0,0 +1,4 @@
+fn main() {
+    unsafe {}
+    ()
+}
diff --git a/gcc/testsuite/rust/compile/torture/unsafe3.rs b/gcc/testsuite/rust/compile/torture/unsafe3.rs
new file mode 100644
index 00000000000..5f427258f60
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/unsafe3.rs
@@ -0,0 +1,9 @@
+pub fn test() -> i32 {
+    let a = unsafe { 123 };
+    a
+}
+
+pub fn main() {
+    let a = test();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/unsafe4.rs b/gcc/testsuite/rust/compile/torture/unsafe4.rs
new file mode 100644
index 00000000000..6fe3101d49c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/unsafe4.rs
@@ -0,0 +1,12 @@
+struct SS {
+    one: i32,
+    two: i32,
+}
+struct TS(i32, i32);
+
+fn main() {
+    unsafe {
+        let ss = SS { one: 1, two: 2 };
+        let _ts = TS(ss.one, ss.two);
+    };
+}
diff --git a/gcc/testsuite/rust/compile/torture/unused.rs b/gcc/testsuite/rust/compile/torture/unused.rs
new file mode 100644
index 00000000000..d95e6b01c00
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/unused.rs
@@ -0,0 +1,17 @@
+// { dg-warning "function is never used: 'bar'" "" { target *-*-* } .+1 }
+fn bar() {
+    foo();
+}
+
+// { dg-warning "function is never used: 'foo'" "" { target *-*-* } .+1 }
+fn foo() {
+    bar();
+}
+
+fn f() {
+
+}
+
+fn main() {
+    f();
+}
diff --git a/gcc/testsuite/rust/compile/torture/unused1.rs b/gcc/testsuite/rust/compile/torture/unused1.rs
new file mode 100644
index 00000000000..db7eb8fc1fc
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/unused1.rs
@@ -0,0 +1,15 @@
+fn test() -> i32 {
+    1
+}
+
+fn unused() -> i32 {
+    // { dg-warning "function is never used: 'unused'" "" { target *-*-* } .-1 }
+    2
+}
+
+fn main() {
+    let a = 1;
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+    let b = test();
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/unused_struct.rs b/gcc/testsuite/rust/compile/torture/unused_struct.rs
new file mode 100644
index 00000000000..ba9ec3250cf
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/unused_struct.rs
@@ -0,0 +1,7 @@
+struct Foo {
+    // { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+    one: i32,
+    two: i32,
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/torture/unused_struct_field.rs b/gcc/testsuite/rust/compile/torture/unused_struct_field.rs
new file mode 100644
index 00000000000..429b3039da4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/unused_struct_field.rs
@@ -0,0 +1,9 @@
+struct Foo {
+    one: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+    two: i32
+}
+fn main() {
+    let _a = Foo {one: 1, two: 2};
+    let _b = _a.two;
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/torture/usize1.rs b/gcc/testsuite/rust/compile/torture/usize1.rs
new file mode 100644
index 00000000000..ba1d5c60320
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/usize1.rs
@@ -0,0 +1,6 @@
+fn main() {
+    let a = [1, 2, 3];
+    let b: usize = 1;
+    let c = a[b];
+    // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/torture/very-broken-attr-string.rs b/gcc/testsuite/rust/compile/torture/very-broken-attr-string.rs
new file mode 100644
index 00000000000..832ba7b8ec9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/very-broken-attr-string.rs
@@ -0,0 +1,3 @@
+// { dg-excess-errors "...." }
+// { dg-error "unended string literal" "" { target *-*-* } .+1 }
+#[doc(alias = "123
diff --git a/gcc/testsuite/rust/compile/torture/while_function.rs b/gcc/testsuite/rust/compile/torture/while_function.rs
new file mode 100644
index 00000000000..014db902769
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/while_function.rs
@@ -0,0 +1,10 @@
+fn foo() {}
+fn bar() -> i32 { return 10; }
+
+fn main() {
+	let mut i = 1;
+	while i < bar() {
+		foo();
+		i += 1;
+	}
+}
diff --git a/gcc/testsuite/rust/compile/traits1.rs b/gcc/testsuite/rust/compile/traits1.rs
new file mode 100644
index 00000000000..355064eec1a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/traits1.rs
@@ -0,0 +1,13 @@
+trait Foo {
+    fn Bar() -> i32 {}
+    // { dg-error "expected .i32. got .()." "" { target *-*-* } .-1 }
+}
+
+struct Baz;
+
+impl Foo for Baz {
+    fn Barrr() {}
+    // { dg-error "method .Barrr. is not a member of trait .Foo." "" { target *-*-* } .-1 }
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/traits10.rs b/gcc/testsuite/rust/compile/traits10.rs
new file mode 100644
index 00000000000..f8f551ba86d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/traits10.rs
@@ -0,0 +1,15 @@
+struct Foo(i32);
+
+trait Bar {
+    const A: i32 = 123;
+    fn B();
+    fn C(&self);
+}
+
+pub fn main() {
+    let a;
+    a = Foo(123);
+
+    let b: &dyn Bar = &a;
+    // { dg-error "trait bound is not object safe" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/traits11.rs b/gcc/testsuite/rust/compile/traits11.rs
new file mode 100644
index 00000000000..d06e47d7e16
--- /dev/null
+++ b/gcc/testsuite/rust/compile/traits11.rs
@@ -0,0 +1,19 @@
+struct Foo(i32);
+
+trait A {
+    const A: i32 = 123;
+    fn B();
+    fn C(&self);
+}
+
+trait B: A {
+    fn test(&self);
+}
+
+pub fn main() {
+    let a;
+    a = Foo(123);
+
+    let b: &dyn B = &a;
+    // { dg-error "trait bound is not object safe" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/traits12.rs b/gcc/testsuite/rust/compile/traits12.rs
new file mode 100644
index 00000000000..25e0eb7aaa3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/traits12.rs
@@ -0,0 +1,20 @@
+trait A<T> {
+    type Output;
+
+    fn test(self, a: &T) -> &Self::Output;
+}
+
+struct Foo<T> {
+    start: T,
+    end: T,
+}
+
+impl<T> A for Foo<usize> {
+    // { dg-error "generic item takes at least 1 type arguments but 0 were supplied" "" { target *-*-* } .-1 }
+    // { dg-error "unconstrained type parameter" "" { target *-*-* } .-2 }
+    type Output = T;
+
+    fn test(self, a: &T) -> &Self::Output {
+        a
+    }
+}
diff --git a/gcc/testsuite/rust/compile/traits2.rs b/gcc/testsuite/rust/compile/traits2.rs
new file mode 100644
index 00000000000..7357c22f7d6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/traits2.rs
@@ -0,0 +1,14 @@
+trait Foo {
+    fn Bar() -> i32 {}
+    // { dg-error "expected .i32. got .()." "" { target *-*-* } .-1 }
+}
+
+struct Baz;
+
+impl Foo for Baz {
+    fn Bar() {}
+    // { dg-error "expected .i32. got .()." "" { target *-*-* } .-1 }
+    // { dg-error "method .Bar. has an incompatible type for trait .Foo." "" { target *-*-* } .-2 }
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/traits3.rs b/gcc/testsuite/rust/compile/traits3.rs
new file mode 100644
index 00000000000..fd3fa457cc8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/traits3.rs
@@ -0,0 +1,22 @@
+trait Foo {
+    type A;
+
+    fn baz(a: Self::A) -> Self::A;
+}
+
+struct Bar<T>(T);
+
+impl<T> Foo for Bar<T> {
+    type A = i32;
+
+    fn baz(a: f32) -> f32 {
+        // { dg-error "method .baz. has an incompatible type for trait .Foo." "" { target *-*-* } .-1 }
+        a
+        // { dg-error "expected .i32. got .f32." "" { target *-*-* } .-1 }
+    }
+}
+
+fn main() {
+    let a;
+    a = Bar::<i32>::baz(123f32);
+}
diff --git a/gcc/testsuite/rust/compile/traits4.rs b/gcc/testsuite/rust/compile/traits4.rs
new file mode 100644
index 00000000000..486301d6136
--- /dev/null
+++ b/gcc/testsuite/rust/compile/traits4.rs
@@ -0,0 +1,16 @@
+trait Foo {
+    const A: i32;
+
+    fn test(self);
+}
+
+struct Bar;
+impl Foo for Bar {
+    // { dg-error "missing A in implementation of trait .Foo." "" { target *-*-* } .-1 }
+    fn test(self) {}
+}
+
+fn main() {
+    let a = Bar;
+    a.test();
+}
diff --git a/gcc/testsuite/rust/compile/traits5.rs b/gcc/testsuite/rust/compile/traits5.rs
new file mode 100644
index 00000000000..8b2fb9bc10d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/traits5.rs
@@ -0,0 +1,9 @@
+trait Foo {
+    const A: i32;
+
+    fn test(self);
+}
+
+struct Bar;
+impl Foo for Bar {}
+// { dg-error "missing A, test in implementation of trait .Foo." "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/traits6.rs b/gcc/testsuite/rust/compile/traits6.rs
new file mode 100644
index 00000000000..3579b5a0842
--- /dev/null
+++ b/gcc/testsuite/rust/compile/traits6.rs
@@ -0,0 +1,15 @@
+trait Foo {
+    fn default() -> i32;
+}
+
+struct Bar(i32);
+
+fn type_bound_test<T: Foo>() -> i32 {
+    T::default()
+}
+
+fn main() {
+    let a;
+    a = type_bound_test::<Bar>();
+    // { dg-error "bounds not satisfied for Bar" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/traits7.rs b/gcc/testsuite/rust/compile/traits7.rs
new file mode 100644
index 00000000000..825553ce496
--- /dev/null
+++ b/gcc/testsuite/rust/compile/traits7.rs
@@ -0,0 +1,24 @@
+trait Foo {
+    fn default() -> i32;
+}
+
+trait Bar {
+    fn not_default() -> i32;
+}
+
+struct Test(i32);
+
+impl Foo for Test {
+    fn default() -> i32 {
+        1234
+    }
+}
+
+fn type_bound_test<T: Foo + Bar>() -> i32 {
+    T::default()
+}
+
+fn main() {
+    let a = type_bound_test::<Test>();
+    // { dg-error "bounds not satisfied for Test" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/traits8.rs b/gcc/testsuite/rust/compile/traits8.rs
new file mode 100644
index 00000000000..b22590a52bb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/traits8.rs
@@ -0,0 +1,35 @@
+trait A {
+    fn get(self) -> f64;
+}
+
+trait B {
+    fn get(self) -> u8;
+}
+
+struct Foo(u8, f64);
+
+impl A for Foo {
+    fn get(self) -> f64 {
+        self.1
+    }
+}
+
+impl B for Foo {
+    fn get(self) -> u8 {
+        self.0
+    }
+}
+
+fn main() {
+    let _a;
+    _a = Foo(123, 456f64);
+
+    let _b: f64;
+    _b = <Foo as A>::get(_a);
+
+    let _a;
+    _a = Foo(123, 456f64);
+
+    let _c: u8;
+    _c = <Foo as B>::get(_a)
+}
diff --git a/gcc/testsuite/rust/compile/traits9.rs b/gcc/testsuite/rust/compile/traits9.rs
new file mode 100644
index 00000000000..e1aef5397fc
--- /dev/null
+++ b/gcc/testsuite/rust/compile/traits9.rs
@@ -0,0 +1,13 @@
+struct Foo(i32);
+trait Bar {
+    fn baz(&self);
+}
+
+fn main() {
+    let a;
+    a = Foo(123);
+
+    let b: &dyn Bar = &a;
+    // { dg-error "bounds not satisfied for Foo .Bar. is not satisfied" "" { target *-*-* } .-1 }
+    // { dg-error "expected" "" { target *-*-* } .-2 }
+}
diff --git a/gcc/testsuite/rust/compile/tuple1.rs b/gcc/testsuite/rust/compile/tuple1.rs
new file mode 100644
index 00000000000..84179b13727
--- /dev/null
+++ b/gcc/testsuite/rust/compile/tuple1.rs
@@ -0,0 +1,5 @@
+fn main() {
+    let a: (i32, bool) = (123, 123); // { dg-error "expected .bool. got .<integer>." }
+    let b;
+    b = (456, 5f32);
+}
diff --git a/gcc/testsuite/rust/compile/tuple_struct1.rs b/gcc/testsuite/rust/compile/tuple_struct1.rs
new file mode 100644
index 00000000000..2f4cb4a353b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/tuple_struct1.rs
@@ -0,0 +1,8 @@
+struct Foo {
+    one: i32,
+    two: i32,
+}
+
+fn main() {
+    let a = Foo(1, 2); // { dg-error "expected function, tuple struct or tuple variant, found struct 'Foo'" }
+}
diff --git a/gcc/testsuite/rust/compile/tuple_struct2.rs b/gcc/testsuite/rust/compile/tuple_struct2.rs
new file mode 100644
index 00000000000..1fc18968577
--- /dev/null
+++ b/gcc/testsuite/rust/compile/tuple_struct2.rs
@@ -0,0 +1,5 @@
+struct Bar(i32, i32, bool);
+
+fn main() {
+    let a = Bar(1, 2); // { dg-error "unexpected number of arguments 2 expected 3" }
+}
diff --git a/gcc/testsuite/rust/compile/tuple_struct3.rs b/gcc/testsuite/rust/compile/tuple_struct3.rs
new file mode 100644
index 00000000000..4af66b8370e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/tuple_struct3.rs
@@ -0,0 +1,6 @@
+struct Foo(i32, i32, bool);
+
+fn main() {
+    let c = Foo(1, 2f32, true);
+    // { dg-error "expected .i32. got .f32." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/type-alias1.rs b/gcc/testsuite/rust/compile/type-alias1.rs
new file mode 100644
index 00000000000..c7d7048246a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/type-alias1.rs
@@ -0,0 +1,6 @@
+type TypeAlias = (i32, u32);
+
+fn main() {
+    let a: TypeAlias;
+    a = (123, 456f32); // { dg-error "expected .u32. got .f32." }
+}
diff --git a/gcc/testsuite/rust/compile/type-bindings1.rs b/gcc/testsuite/rust/compile/type-bindings1.rs
new file mode 100644
index 00000000000..ad85ed97ecb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/type-bindings1.rs
@@ -0,0 +1,10 @@
+struct Foo<A, B>(A, B);
+
+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 type resolve expression} "" { target *-*-* } .-2 }
+    // { dg-error {Failed to resolve expression of function call} "" { target *-*-* } .-3 }
+    // { duplicate _dg-error {failed to type resolve expression} "" { target *-*-* } .-4 }
+}
diff --git a/gcc/testsuite/rust/compile/unary_negation.rs b/gcc/testsuite/rust/compile/unary_negation.rs
new file mode 100644
index 00000000000..848643f0bd2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/unary_negation.rs
@@ -0,0 +1,9 @@
+fn main() {
+    let a: i32 = -1;
+    let b: i32 = 3 - -1;
+    let c: bool = !false;
+    let d: i32 = !3;
+
+    let e: f32 = -true; // // { dg-error "cannot apply unary - to bool" }
+    // { dg-error {failed to type resolve expression} "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/unary_not.rs b/gcc/testsuite/rust/compile/unary_not.rs
new file mode 100644
index 00000000000..b0a3dafbbd0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/unary_not.rs
@@ -0,0 +1,9 @@
+fn main() {
+    let a: i32 = -1;
+    let b: i32 = 3 - -1;
+    let c: bool = !false;
+    let d: i32 = !3;
+
+    let e: f32 = !5f32; // { dg-error "cannot apply unary '!' to f32" }
+    // { dg-error {failed to type resolve expression} "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/unconstrained_type_param.rs b/gcc/testsuite/rust/compile/unconstrained_type_param.rs
new file mode 100644
index 00000000000..c4aaa10146f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/unconstrained_type_param.rs
@@ -0,0 +1,12 @@
+struct Foo<T>(T, bool);
+
+impl<X, Y> Foo<X> {
+    // { dg-error "unconstrained type parameter" "" { target *-*-* } .-1 }
+    fn test() -> Y {
+        123
+    }
+}
+
+fn main() {
+    let a = Foo::test();
+}
diff --git a/gcc/testsuite/rust/compile/unicode_escape.rs b/gcc/testsuite/rust/compile/unicode_escape.rs
new file mode 100644
index 00000000000..39b91d8a95c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/unicode_escape.rs
@@ -0,0 +1,60 @@
+fn main ()
+{
+  // Braces are required
+  let _cbl = '\u013'; // { dg-error "unicode escape" }
+  let _sbl = "\u013"; //{ dg-error "unicode escape" }
+
+  // One to six hex digits
+  let _c0 = '\u{}'; // { dg-error "unicode escape" }
+  let _c1 = '\u{0}';
+  let _c2 = '\u{00}';
+  let _c3 = '\u{000}';
+  let _c4 = '\u{0000}';
+  let _c5 = '\u{00000}';
+  let _c6 = '\u{000000}';
+  let _c7 = '\u{0000000}'; // { dg-error "unicode escape" }
+
+  let _s0 = "\u{}"; // { dg-error "unicode escape" }
+  let _s1 = "\u{0}";
+  let _s2 = "\u{00}";
+  let _s3 = "\u{000}";
+  let _s4 = "\u{0000}";
+  let _s5 = "\u{00000}";
+  let _s6 = "\u{000000}";
+  let _s7 = "\u{0000000}"; // { dg-error "unicode escape" }
+
+  // Underscores OK except for start
+  let _c_ = '\u{00___01__0_1_}';
+  let _s_ = "\u{00___01__0_1_}";
+  let _c__ = '\u{_00__01__0_}'; // { dg-error "unicode escape" }
+  let _s__ = "\u{_00__01__0_}"; // { dg-error "unicode escape" }
+
+  // Must be hex chars
+  let _chex = '\u{hex}';  // { dg-error "unicode escape" }
+  let _shex = '\u{hex}';  // { dg-error "unicode escape" }
+
+  // Only valid from 0x0 to 0xD7FF and from 0xE000 to 0x10FFF
+  let _cd7ff = '\u{D7FF}';
+  let _sd7ff = "\u{D7FF}";
+  let _cd800 = '\u{D800}'; // { dg-error "unicode escape" }
+  let _sd800 = "\u{D800}"; // { dg-error "unicode escape" }
+
+  let _cdfff = '\u{DFFF}'; // { dg-error "unicode escape" }
+  let _sdfff = "\u{DFFF}"; // { dg-error "unicode escape" }
+  let _ce000 = '\u{E000}';
+  let _se000 = "\u{E000}";
+
+  let _clast = '\u{10FFFF}';
+  let _slast = "\u{10FFFF}";
+  let _clast1 = '\u{110000}'; // { dg-error "unicode escape" }
+  let _slast1 = "\u{110000}"; // { dg-error "unicode escape" }
+
+  let _cffffff = '\u{FFFFFF}'; // { dg-error "unicode escape" }
+  let _sffffff = "\u{FFFFFF}"; // { dg-error "unicode escape" }
+
+  // unicode escapes cannot be used in bytes or byte strings.
+  // Except in raw byte strings (where they aren't escapes).
+  let _bc = b'\u{000A}'; // { dg-error "unicode escape" }
+  let _bs = b"\u{000A}"; // { dg-error "unicode escape" }
+  let _rbs = br"\u{000A}";
+}
diff --git a/gcc/testsuite/rust/compile/unsafe1.rs b/gcc/testsuite/rust/compile/unsafe1.rs
new file mode 100644
index 00000000000..9cd3f6b4bf2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/unsafe1.rs
@@ -0,0 +1,14 @@
+fn foo(_a: &i32) {}
+fn bar(_a: i32) {}
+
+static mut a: i32 = 15;
+
+fn main() {
+    foo(&a); // { dg-error "use of mutable static" }
+    bar(a); // { dg-error "use of mutable static" }
+
+    unsafe {
+        foo(&a);
+        bar(a);
+    }
+}
diff --git a/gcc/testsuite/rust/compile/unsafe10.rs b/gcc/testsuite/rust/compile/unsafe10.rs
new file mode 100644
index 00000000000..6b6be06b908
--- /dev/null
+++ b/gcc/testsuite/rust/compile/unsafe10.rs
@@ -0,0 +1,12 @@
+extern "rust-intrinsic" {
+    pub fn rotate_left<T>(l: T, r: T) -> T;
+}
+
+fn main() -> i32 {
+    let a = 15;
+    let b = 15;
+
+    let _ = rotate_left(a, b);
+
+    0
+}
diff --git a/gcc/testsuite/rust/compile/unsafe2.rs b/gcc/testsuite/rust/compile/unsafe2.rs
new file mode 100644
index 00000000000..e03e4bc59f4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/unsafe2.rs
@@ -0,0 +1,16 @@
+fn foo(_a: &i32) {}
+fn bar(_a: i32) {}
+
+mod inner {
+    pub static mut a: i32 = 15;
+}
+
+fn main() {
+    foo(&inner::a); // { dg-error "use of mutable static" }
+    bar(inner::a); // { dg-error "use of mutable static" }
+
+    unsafe {
+        foo(&inner::a);
+        bar(inner::a);
+    }
+}
diff --git a/gcc/testsuite/rust/compile/unsafe3.rs b/gcc/testsuite/rust/compile/unsafe3.rs
new file mode 100644
index 00000000000..56aec76008a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/unsafe3.rs
@@ -0,0 +1,10 @@
+extern "C" {
+    static VALUE: char;
+}
+
+fn main() {
+    let _ = VALUE; // { dg-error "use of extern static" }
+    unsafe {
+        let _ = VALUE;
+    }
+}
diff --git a/gcc/testsuite/rust/compile/unsafe4.rs b/gcc/testsuite/rust/compile/unsafe4.rs
new file mode 100644
index 00000000000..7d1356bc3e5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/unsafe4.rs
@@ -0,0 +1,29 @@
+fn foo() -> i32 {
+    let a = 15;
+    let p_a = &a as *const i32;
+
+    unsafe { *p_a }
+}
+
+unsafe fn bar() -> i32 {
+    let a = 15;
+    let p_a = &a as *const i32;
+
+    *p_a
+}
+
+fn baz() -> i32 {
+    let a = 15;
+    let p_a = &a as *const i32;
+
+    *p_a // { dg-error "dereference of raw pointer" }
+}
+
+unsafe fn qux() -> i32 {
+    let a = 15;
+    let p_a = &a as *const i32;
+
+    unsafe {}
+
+    *p_a
+}
diff --git a/gcc/testsuite/rust/compile/unsafe5.rs b/gcc/testsuite/rust/compile/unsafe5.rs
new file mode 100644
index 00000000000..35990f6ee9f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/unsafe5.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let b = 15;
+    let c = *(&b as *const i32); // { dg-error "dereference of raw pointer" }
+}
diff --git a/gcc/testsuite/rust/compile/unsafe6.rs b/gcc/testsuite/rust/compile/unsafe6.rs
new file mode 100644
index 00000000000..cf4b75456e4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/unsafe6.rs
@@ -0,0 +1,14 @@
+unsafe fn foo() {}
+unsafe fn bar() {
+    foo();
+}
+
+fn main() {
+    foo(); // { dg-error "call to unsafe function" }
+    bar(); // { dg-error "call to unsafe function" }
+
+    unsafe {
+        foo();
+        bar();
+    }
+}
diff --git a/gcc/testsuite/rust/compile/unsafe7.rs b/gcc/testsuite/rust/compile/unsafe7.rs
new file mode 100644
index 00000000000..a6b69e1ac37
--- /dev/null
+++ b/gcc/testsuite/rust/compile/unsafe7.rs
@@ -0,0 +1,9 @@
+extern "C" {
+    fn printf(fmt: *const i8, ...);
+}
+
+fn main() {
+    let s = "hey\0";
+
+    printf(s as *const str as *const i8); // { dg-error "call to extern function" }
+}
diff --git a/gcc/testsuite/rust/compile/unsafe8.rs b/gcc/testsuite/rust/compile/unsafe8.rs
new file mode 100644
index 00000000000..03fe4910c97
--- /dev/null
+++ b/gcc/testsuite/rust/compile/unsafe8.rs
@@ -0,0 +1,14 @@
+struct S;
+
+impl S {
+    unsafe fn foo(self) {}
+}
+
+fn main() {
+    let s = S;
+    s.foo(); // { dg-error "call to unsafe method" }
+
+    unsafe {
+        s.foo();
+    }
+}
diff --git a/gcc/testsuite/rust/compile/unsafe9.rs b/gcc/testsuite/rust/compile/unsafe9.rs
new file mode 100644
index 00000000000..fb46c8ffde3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/unsafe9.rs
@@ -0,0 +1,10 @@
+union U {
+    a: i32,
+    b: f32,
+    c: u8,
+}
+
+fn main() {
+    let u = U { a: 14 };
+    let _ = u.a; // { dg-error "access to union" }
+}
diff --git a/gcc/testsuite/rust/compile/unterminated_c_comment.rs b/gcc/testsuite/rust/compile/unterminated_c_comment.rs
new file mode 100644
index 00000000000..619b7b7024d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/unterminated_c_comment.rs
@@ -0,0 +1,2 @@
+// { dg-error "unexpected EOF while looking for end of comment" "" { target *-*-* } .+1 }
+/* This  comment needs closure :) !
diff --git a/gcc/testsuite/rust/compile/use_1.rs b/gcc/testsuite/rust/compile/use_1.rs
new file mode 100644
index 00000000000..94b96321a63
--- /dev/null
+++ b/gcc/testsuite/rust/compile/use_1.rs
@@ -0,0 +1,16 @@
+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." }
+
+mod sain {
+    mod doux {}
+
+    mod dron {}
+}
+
+use not_sain::*; // { dg-error "cannot find simple path segment .not_sain." }
+
+use sain::*;
+use sain::{doux, dron};
+use sain::{doux, dron, graal}; // { dg-error "cannot find simple path segment .graal." }
diff --git a/gcc/testsuite/rust/compile/usize1.rs b/gcc/testsuite/rust/compile/usize1.rs
new file mode 100644
index 00000000000..b1c8fe86473
--- /dev/null
+++ b/gcc/testsuite/rust/compile/usize1.rs
@@ -0,0 +1,6 @@
+fn main() {
+    let a = [1, 2, 3];
+    let b: u32 = 1;
+    let c = a[b]; // { dg-error "the type ...integer..CAPACITY.. cannot be indexed by .u32." }
+                  // { dg-error {failed to type resolve expression} "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/xfail/lifetime_param.rs b/gcc/testsuite/rust/compile/xfail/lifetime_param.rs
new file mode 100644
index 00000000000..306fca0b3c5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/xfail/lifetime_param.rs
@@ -0,0 +1,11 @@
+// { dg-excess-errors "warnings" }
+
+// { dg-error "lifetime not defined" "#359" { xfail *-*-* } .+1 }
+fn lifetime_undefined(t: &'a str) -> &'a str {
+    t
+}
+
+// { dg-error "lifetime not defined" "#359" { xfail *-*-* } .+1 }
+fn lifetime_undefined_bis<'a>(t: &'a str)-> &'b str {
+    t
+}
diff --git a/gcc/testsuite/rust/compile/xfail/struct_field_vis.rs b/gcc/testsuite/rust/compile/xfail/struct_field_vis.rs
new file mode 100644
index 00000000000..a28729e6208
--- /dev/null
+++ b/gcc/testsuite/rust/compile/xfail/struct_field_vis.rs
@@ -0,0 +1,15 @@
+// { dg-xfail-if "pub visibility not supported #432"  *-*-* }
+
+mod foomod {
+    pub struct Foo {
+        pub f: i32,
+        pub g: u32,
+    }
+}
+
+fn test() -> foomod::Foo {
+    foomod::Foo{
+        f:1,
+        g:3,
+    }
+}
diff --git a/gcc/testsuite/rust/compile/xfail/xfail.exp b/gcc/testsuite/rust/compile/xfail/xfail.exp
new file mode 100644
index 00000000000..5fb6203bb31
--- /dev/null
+++ b/gcc/testsuite/rust/compile/xfail/xfail.exp
@@ -0,0 +1,63 @@
+# Copyright (C) 2021-2022 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 are used to keep track of known limitations :
+# 1- tests that are incorrecly build instead of being rejected
+# 2- tests that are build to an incorrect result
+# 3- tests that are rejected instead of being correctly build
+#
+# Not currently supported here:
+# - tests that are exhibiting incorrect behavior at runtime
+#
+# Here's how to annotate tests for each cases:
+#
+# 1- test is successfuly build instead of being rejected
+#
+# Expected behavior: a specific error rejecting the test
+# Observed behavior: error not present
+# Use dg-error and mark the test xfail and add reference to corresponding issue.
+# { dg-error "lifetime not defined" "#359" { xfail *-*-* } }
+#
+# 2- test is successfuly build but result is incorrect
+#
+# Expected behavior: test is correctly build and has specific property
+# Observed behavior: test is correctly build but is missing the specific property
+# Depends on the property. For example, if the property can be checked in the assembly file, use dg-final + xfail.
+# { dg-final { scan-assembler "given_string_missing_in_assembly_" "#1234" { xfail *-*-* } } }
+#
+# 3- test is rejected instead of being correctly build
+#
+# Expected behavior: test is successfully build
+# Observed behavior: the test is rejected with an error
+# Use dg-bogus + xfail to match the bogus error message, or use dg-xfail-if if it's harder to match a specific error.
+
+# 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
