about summary refs log tree commit diff
path: root/tests/ui/rfcs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/rfcs')
-rw-r--r--tests/ui/rfcs/rfc-1014-2.rs31
-rw-r--r--tests/ui/rfcs/rfc-1014.rs34
-rw-r--r--tests/ui/rfcs/rfc-1789-as-cell/from-mut.rs20
-rw-r--r--tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs6
-rw-r--r--tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs2
-rw-r--r--tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs7
-rw-r--r--tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs3
-rw-r--r--tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs6
-rw-r--r--tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs6
-rw-r--r--tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs4
-rw-r--r--tests/ui/rfcs/rfc-2005-default-binding-mode/box.rs18
-rw-r--r--tests/ui/rfcs/rfc-2005-default-binding-mode/constref.rs40
-rw-r--r--tests/ui/rfcs/rfc-2005-default-binding-mode/enum.rs45
-rw-r--r--tests/ui/rfcs/rfc-2005-default-binding-mode/for.rs20
-rw-r--r--tests/ui/rfcs/rfc-2005-default-binding-mode/general.rs249
-rw-r--r--tests/ui/rfcs/rfc-2005-default-binding-mode/lit.rs34
-rw-r--r--tests/ui/rfcs/rfc-2005-default-binding-mode/range.rs9
-rw-r--r--tests/ui/rfcs/rfc-2005-default-binding-mode/ref-region.rs16
-rw-r--r--tests/ui/rfcs/rfc-2005-default-binding-mode/reset-mode.rs14
-rw-r--r--tests/ui/rfcs/rfc-2005-default-binding-mode/slice.rs25
-rw-r--r--tests/ui/rfcs/rfc-2005-default-binding-mode/struct.rs22
-rw-r--r--tests/ui/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs19
-rw-r--r--tests/ui/rfcs/rfc-2005-default-binding-mode/tuple.rs12
-rw-r--r--tests/ui/rfcs/rfc-2151-raw-identifiers/attr.rs15
-rw-r--r--tests/ui/rfcs/rfc-2151-raw-identifiers/basic.rs20
-rw-r--r--tests/ui/rfcs/rfc-2151-raw-identifiers/items.rs32
-rw-r--r--tests/ui/rfcs/rfc-2151-raw-identifiers/macros.rs38
-rw-r--r--tests/ui/rfcs/rfc-2175-or-if-while-let/basic.rs33
-rw-r--r--tests/ui/rfcs/rfc-2302-self-struct-ctor.rs127
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/check-pass.rs52
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/closures-inherit-target_feature.rs20
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/feature-gate-target_feature_11.rs6
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/feature-gate-target_feature_11.stderr14
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.mir.stderr18
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.rs12
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.thir.stderr18
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs34
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr105
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/issue-99876.rs9
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.mir.stderr83
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs69
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.thir.stderr83
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.rs21
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.stderr11
-rw-r--r--tests/ui/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs15
-rw-r--r--tests/ui/rfcs/rfc-2528-type-changing-struct-update/coerce-in-base-expr.rs28
-rw-r--r--tests/ui/rfcs/rfc-2528-type-changing-struct-update/feature-gate.rs29
-rw-r--r--tests/ui/rfcs/rfc-2528-type-changing-struct-update/feature-gate.stderr22
-rw-r--r--tests/ui/rfcs/rfc-2528-type-changing-struct-update/issue-92010-trait-bound-not-satisfied.rs12
-rw-r--r--tests/ui/rfcs/rfc-2528-type-changing-struct-update/issue-92010-trait-bound-not-satisfied.stderr12
-rw-r--r--tests/ui/rfcs/rfc-2528-type-changing-struct-update/issue-96878.rs31
-rw-r--r--tests/ui/rfcs/rfc-2528-type-changing-struct-update/lifetime-update.rs43
-rw-r--r--tests/ui/rfcs/rfc-2528-type-changing-struct-update/lifetime-update.stderr15
-rw-r--r--tests/ui/rfcs/rfc-2528-type-changing-struct-update/type-generic-update.rs56
-rw-r--r--tests/ui/rfcs/rfc-2528-type-changing-struct-update/type-generic-update.stderr21
-rw-r--r--tests/ui/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs23
-rw-r--r--tests/ui/rfcs/rfc1445/eq-allows-match.rs17
-rw-r--r--tests/ui/rfcs/rfc1623-2.rs99
-rw-r--r--tests/ui/rfcs/rfc1623-2.stderr39
-rw-r--r--tests/ui/rfcs/rfc1623-3.rs14
-rw-r--r--tests/ui/rfcs/rfc1623-3.stderr35
-rw-r--r--tests/ui/rfcs/rfc1623.rs75
-rw-r--r--tests/ui/rfcs/rfc1717/library-override.rs14
-rw-r--r--tests/ui/rfcs/rfc1857-drop-order.rs224
64 files changed, 2286 insertions, 0 deletions
diff --git a/tests/ui/rfcs/rfc-1014-2.rs b/tests/ui/rfcs/rfc-1014-2.rs
new file mode 100644
index 00000000000..7dd65701f12
--- /dev/null
+++ b/tests/ui/rfcs/rfc-1014-2.rs
@@ -0,0 +1,31 @@
+// run-pass
+#![allow(dead_code)]
+
+#![feature(rustc_private)]
+
+extern crate libc;
+
+type DWORD = u32;
+type HANDLE = *mut u8;
+type BOOL = i32;
+
+#[cfg(windows)]
+extern "system" {
+    fn SetStdHandle(nStdHandle: DWORD, nHandle: HANDLE) -> BOOL;
+}
+
+#[cfg(windows)]
+fn close_stdout() {
+    const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD;
+    unsafe { SetStdHandle(STD_OUTPUT_HANDLE, 0 as HANDLE); }
+}
+
+#[cfg(windows)]
+fn main() {
+    close_stdout();
+    println!("hello");
+    println!("world");
+}
+
+#[cfg(not(windows))]
+fn main() {}
diff --git a/tests/ui/rfcs/rfc-1014.rs b/tests/ui/rfcs/rfc-1014.rs
new file mode 100644
index 00000000000..c454dfa4eb9
--- /dev/null
+++ b/tests/ui/rfcs/rfc-1014.rs
@@ -0,0 +1,34 @@
+// run-pass
+#![allow(dead_code)]
+// ignore-wasm32-bare no libc
+// ignore-sgx no libc
+
+#![feature(rustc_private)]
+
+extern crate libc;
+
+type DWORD = u32;
+type HANDLE = *mut u8;
+
+#[cfg(windows)]
+extern "system" {
+    fn GetStdHandle(which: DWORD) -> HANDLE;
+    fn CloseHandle(handle: HANDLE) -> i32;
+}
+
+#[cfg(windows)]
+fn close_stdout() {
+    const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD;
+    unsafe { CloseHandle(GetStdHandle(STD_OUTPUT_HANDLE)); }
+}
+
+#[cfg(not(windows))]
+fn close_stdout() {
+    unsafe { libc::close(1); }
+}
+
+fn main() {
+    close_stdout();
+    println!("hello");
+    println!("world");
+}
diff --git a/tests/ui/rfcs/rfc-1789-as-cell/from-mut.rs b/tests/ui/rfcs/rfc-1789-as-cell/from-mut.rs
new file mode 100644
index 00000000000..329fadb150f
--- /dev/null
+++ b/tests/ui/rfcs/rfc-1789-as-cell/from-mut.rs
@@ -0,0 +1,20 @@
+// run-pass
+
+#![feature(as_array_of_cells)]
+
+use std::cell::Cell;
+
+fn main() {
+    let slice: &mut [i32] = &mut [1, 2, 3];
+    let cell_slice: &Cell<[i32]> = Cell::from_mut(slice);
+    let slice_cell: &[Cell<i32>] = cell_slice.as_slice_of_cells();
+
+    assert_eq!(slice_cell.len(), 3);
+
+    let mut array: [i32; 3] = [1, 2, 3];
+    let cell_array: &Cell<[i32; 3]> = Cell::from_mut(&mut array);
+    let array_cell: &[Cell<i32>; 3] = cell_array.as_array_of_cells();
+
+    array_cell[0].set(99);
+    assert_eq!(array, [99, 2, 3]);
+}
diff --git a/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs b/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs
new file mode 100644
index 00000000000..e98582cbce3
--- /dev/null
+++ b/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs
@@ -0,0 +1,6 @@
+// run-pass
+use std::error::Error;
+
+fn main() -> Result<(), Box<dyn Error>> {
+    Ok(())
+}
diff --git a/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs b/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs
new file mode 100644
index 00000000000..bac695d4e79
--- /dev/null
+++ b/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs
@@ -0,0 +1,2 @@
+// run-pass
+fn main() {}
diff --git a/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs b/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs
new file mode 100644
index 00000000000..6d4c1562053
--- /dev/null
+++ b/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs
@@ -0,0 +1,7 @@
+// run-pass
+
+use std::process::ExitCode;
+
+fn main() -> ExitCode {
+    ExitCode::SUCCESS
+}
diff --git a/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs b/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs
new file mode 100644
index 00000000000..c06a135dcbc
--- /dev/null
+++ b/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs
@@ -0,0 +1,3 @@
+// run-pass
+
+fn main() -> impl std::process::Termination { }
diff --git a/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs b/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs
new file mode 100644
index 00000000000..b0e932e1fe0
--- /dev/null
+++ b/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs
@@ -0,0 +1,6 @@
+// run-pass
+use std::io::Error;
+
+fn main() -> Result<(), Box<Error>> {
+    Ok(())
+}
diff --git a/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs b/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs
new file mode 100644
index 00000000000..30f36c24489
--- /dev/null
+++ b/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs
@@ -0,0 +1,6 @@
+// run-pass
+use std::io::Error;
+
+fn main() -> Result<(), Error> {
+    Ok(())
+}
diff --git a/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs b/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs
new file mode 100644
index 00000000000..f0591c38c00
--- /dev/null
+++ b/tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs
@@ -0,0 +1,4 @@
+// run-pass
+fn main() -> Result<(), &'static str> {
+    Ok(())
+}
diff --git a/tests/ui/rfcs/rfc-2005-default-binding-mode/box.rs b/tests/ui/rfcs/rfc-2005-default-binding-mode/box.rs
new file mode 100644
index 00000000000..0d1cded36b6
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2005-default-binding-mode/box.rs
@@ -0,0 +1,18 @@
+// run-pass
+#![allow(unreachable_patterns)]
+#![feature(box_patterns)]
+
+struct Foo{}
+
+pub fn main() {
+    let b = Box::new(Foo{});
+    let box f = &b;
+    let _: &Foo = f;
+
+    match &&&b {
+        box f => {
+            let _: &Foo = f;
+        },
+        _ => panic!(),
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2005-default-binding-mode/constref.rs b/tests/ui/rfcs/rfc-2005-default-binding-mode/constref.rs
new file mode 100644
index 00000000000..d5bca6a2474
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2005-default-binding-mode/constref.rs
@@ -0,0 +1,40 @@
+// run-pass
+const CONST_REF: &[u8; 3] = b"foo";
+
+trait Foo {
+    const CONST_REF_DEFAULT: &'static [u8; 3] = b"bar";
+    const CONST_REF: &'static [u8; 3];
+}
+
+impl Foo for i32 {
+    const CONST_REF: &'static [u8; 3] = b"jjj";
+}
+
+impl Foo for i64 {
+    const CONST_REF_DEFAULT: &'static [u8; 3] = b"ggg";
+    const CONST_REF: &'static [u8; 3] = b"fff";
+}
+
+// Check that (associated and free) const references are not mistaken for a
+// non-reference pattern (in which case they would be auto-dereferenced, making
+// the types mismatched).
+
+fn const_ref() -> bool {
+    let f = b"foo";
+    match f {
+        CONST_REF => true,
+        _ => false,
+    }
+}
+
+fn associated_const_ref() -> bool {
+    match (b"bar", b"jjj", b"ggg", b"fff") {
+        (i32::CONST_REF_DEFAULT, i32::CONST_REF, i64::CONST_REF_DEFAULT, i64::CONST_REF) => true,
+        _ => false,
+    }
+}
+
+pub fn main() {
+    assert!(const_ref());
+    assert!(associated_const_ref());
+}
diff --git a/tests/ui/rfcs/rfc-2005-default-binding-mode/enum.rs b/tests/ui/rfcs/rfc-2005-default-binding-mode/enum.rs
new file mode 100644
index 00000000000..52fbb90ed54
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2005-default-binding-mode/enum.rs
@@ -0,0 +1,45 @@
+// run-pass
+enum Wrapper {
+    Wrap(i32),
+}
+
+use Wrapper::Wrap;
+
+pub fn main() {
+    let Wrap(x) = &Wrap(3);
+    println!("{}", *x);
+
+    let Wrap(x) = &mut Wrap(3);
+    println!("{}", *x);
+
+    if let Some(x) = &Some(3) {
+        println!("{}", *x);
+    } else {
+        panic!();
+    }
+
+    if let Some(x) = &mut Some(3) {
+        println!("{}", *x);
+    } else {
+        panic!();
+    }
+
+    if let Some(x) = &mut Some(3) {
+        *x += 1;
+    } else {
+        panic!();
+    }
+
+    while let Some(x) = &Some(3) {
+        println!("{}", *x);
+        break;
+    }
+    while let Some(x) = &mut Some(3) {
+        println!("{}", *x);
+        break;
+    }
+    while let Some(x) = &mut Some(3) {
+        *x += 1;
+        break;
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2005-default-binding-mode/for.rs b/tests/ui/rfcs/rfc-2005-default-binding-mode/for.rs
new file mode 100644
index 00000000000..a5a24a80634
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2005-default-binding-mode/for.rs
@@ -0,0 +1,20 @@
+// run-pass
+pub fn main() {
+    let mut tups = vec![(0u8, 1u8)];
+
+    for (n, m) in &tups {
+        let _: &u8 = n;
+        let _: &u8 = m;
+    }
+
+    for (n, m) in &mut tups {
+        *n += 1;
+        *m += 2;
+    }
+
+    assert_eq!(tups, vec![(1u8, 3u8)]);
+
+    for (n, m) in tups {
+        println!("{} {}", m, n);
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2005-default-binding-mode/general.rs b/tests/ui/rfcs/rfc-2005-default-binding-mode/general.rs
new file mode 100644
index 00000000000..0207f607be8
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2005-default-binding-mode/general.rs
@@ -0,0 +1,249 @@
+// run-pass
+#![allow(unused_variables)]
+fn some_or_wildcard(r: &Option<i32>, b: &i32) {
+    let _: &i32 = match r {
+        Some(a) => a,
+        _ => b,
+    };
+}
+
+fn none_or_wildcard(r: &Option<i32>, b: &i32) {
+    let _: &i32 = match r {
+        None => b,
+        _ => b,
+    };
+}
+
+fn some_or_ref_none(r: &Option<i32>, b: &i32) {
+    let _: &i32 = match r {
+        Some(a) => a,
+        &None => b,
+    };
+}
+
+fn ref_some_or_none(r: &Option<i32>, b: &i32) {
+    let _: &i32 = match r {
+        &Some(ref a) => a,
+        None => b,
+    };
+}
+
+fn some_or_self(r: &Option<i32>) {
+    let _: &Option<i32> = match r {
+        Some(n) => {
+            let _: &i32 = n;
+            r
+        },
+        x => x,
+    };
+}
+
+fn multiple_deref(r: &&&&&Option<i32>) {
+    let _: i32 = match r {
+        Some(a) => *a,
+        None => 5,
+    };
+}
+
+fn match_with_or() {
+    // FIXME(tschottdorf): #44912.
+    //
+    // let x = &Some((3, 3));
+    // let _: &i32 = match x {
+    //     Some((x, 3)) | &Some((ref x, 5)) => x,
+    //     _ => &5i32,
+    // };
+}
+
+fn nested_mixed() {
+    match (&Some(5), &Some(6)) {
+        (Some(a), &Some(mut b)) => {
+            // Here, the `a` will be `&i32`, because in the first half of the tuple
+            // we hit a non-reference pattern and shift into `ref` mode.
+            //
+            // In the second half of the tuple there's no non-reference pattern,
+            // so `b` will be `i32` (bound with `move` mode). Moreover, `b` is
+            // mutable.
+            let _: &i32 = a;
+            b = 7;
+            let _: i32 = b;
+        },
+        _ => {},
+    };
+}
+
+fn nested_mixed_multiple_deref_1() {
+    let x = (1, &Some(5));
+    let y = &Some(x);
+    match y {
+        Some((a, Some(b))) => {
+            let _: &i32 = a;
+            let _: &i32 = b;
+        },
+        _ => {},
+    };
+}
+
+fn nested_mixed_multiple_deref_2() {
+    let x = &Some(5);
+    let y = &x;
+    match y {
+        Some(z) => {
+            let _: &i32 = z;
+        },
+        _ => {},
+    }
+}
+
+fn new_mutable_reference() {
+    let mut x = &mut Some(5);
+    match &mut x {
+        Some(y) => {
+            *y = 5;
+        },
+        None => { },
+    }
+
+    match &mut x {
+        Some(y) => {
+            println!("{}", *y);
+        },
+        None => {},
+    }
+}
+
+fn let_implicit_ref_binding() {
+    struct Foo(i32);
+
+    // Note that these rules apply to any pattern matching
+    // whether it be in a `match` or a `let`.
+    // For example, `x` here is a `ref` binding:
+    let Foo(x) = &Foo(3);
+    let _: &i32 = x;
+}
+
+fn explicit_mut_binding() {
+    match &Some(5i32) {
+        Some(mut n) => {
+            n += 1;
+            let _ = n;
+        }
+        None => {},
+    };
+
+    match &mut Some(5i32) {
+        Some(n) => {
+            *n += 1;
+            let _ = n;
+        }
+        None => {},
+    };
+
+    match &mut &mut Some(5i32) {
+        Some(n) => {
+             let _: &mut i32 = n;
+        }
+        None => {},
+    };
+}
+
+fn tuple_mut_and_mut_mut() {
+    match (Some(5i32), &Some(5i32)) {
+        (Some(n), Some(m)) => {
+            // `n` and `m` are bound as immutable references. Make new references from them to
+            // assert that.
+            let r = n;
+            let _ = r;
+            let q = m;
+            let _ = q;
+
+            // Assert the types. Note that we use `n` and `m` here which would fail had they been
+            // moved due to the assignments above.
+            let _: i32 = n;
+            let _: &i32 = m;
+        }
+        (_, _) => {},
+    };
+
+    match (&Some(5i32), &&Some(5i32)) {
+        (Some(n), Some(m)) => {
+            let _: &i32 = n;
+            let _: &i32 = m;
+        }
+        (_, _) => {},
+    };
+
+    match &mut &mut (Some(5i32), Some(5i32)) {
+        (Some(n), Some(m)) => {
+            // Dereferenced through &mut &mut, so a mutable binding results.
+            let _: &mut i32 = n;
+            let _: &mut i32 = m;
+        }
+        (_, _) => {},
+    };
+
+    match (&mut Some(5i32), &mut &mut Some(5i32)) {
+        (Some(n), Some(m)) => {
+            let _: &mut i32 = n;
+            let _: &mut i32 = m;
+        }
+        (_, _) => {},
+    };
+}
+
+fn min_mir_embedded_type() {
+    // The reduced invocation that an ICE was diagnosed with (was consuming
+    // adjustments in wrong order).
+    match (0u8, &&Some(5i32)) {
+        (_, Some(m)) => {
+            let _: &i32 = m;
+        }
+        (_, _) => {},
+    };
+}
+
+fn no_autoderef() {
+    // Binding.
+    let x = &3;
+    println!("{}", *x);
+
+    // Wildcard.
+    let _ = &3;
+
+    // Constant of generic type (string)
+    const Y: &'static str = "foo";
+    assert_eq!(0, match "foo" {
+        Y => 0,
+        _ => 1,
+    });
+
+    // Reference pattern.
+    let &x = &3;
+}
+
+pub fn main() {
+    let r: &Option<i32> = &Some(3);
+    let b = &4i32;
+
+    none_or_wildcard(r, b);
+    some_or_wildcard(r, b);
+    some_or_ref_none(r, b);
+    ref_some_or_none(r, b);
+
+    some_or_self(r);
+    multiple_deref(&&&&r);
+    match_with_or();
+
+    nested_mixed();
+    nested_mixed_multiple_deref_1();
+    nested_mixed_multiple_deref_2();
+
+    new_mutable_reference();
+    explicit_mut_binding();
+    tuple_mut_and_mut_mut();
+    min_mir_embedded_type();
+
+    let_implicit_ref_binding();
+
+    no_autoderef();
+}
diff --git a/tests/ui/rfcs/rfc-2005-default-binding-mode/lit.rs b/tests/ui/rfcs/rfc-2005-default-binding-mode/lit.rs
new file mode 100644
index 00000000000..9379753598e
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2005-default-binding-mode/lit.rs
@@ -0,0 +1,34 @@
+// run-pass
+#![allow(dead_code)]
+fn with_u8() {
+    let s = 5u8;
+    let r = match &s {
+        4 => false,
+        5 => true,
+        _ => false,
+    };
+    assert!(r);
+}
+
+// A string literal isn't mistaken for a non-ref pattern (in which case we'd
+// deref `s` and mess things up).
+fn with_str() {
+    let s: &'static str = "abc";
+    match s {
+            "abc" => true,
+            _ => panic!(),
+    };
+}
+
+// Ditto with byte strings.
+fn with_bytes() {
+    let s: &'static [u8] = b"abc";
+    match s {
+        b"abc" => true,
+        _ => panic!(),
+    };
+}
+
+pub fn main() {
+    with_str();
+}
diff --git a/tests/ui/rfcs/rfc-2005-default-binding-mode/range.rs b/tests/ui/rfcs/rfc-2005-default-binding-mode/range.rs
new file mode 100644
index 00000000000..f8abd1b96d8
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2005-default-binding-mode/range.rs
@@ -0,0 +1,9 @@
+// run-pass
+pub fn main() {
+    let i = 5;
+    match &&&&i {
+        1 ..= 3 => panic!(),
+        4 ..= 8 => {},
+        _ => panic!(),
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2005-default-binding-mode/ref-region.rs b/tests/ui/rfcs/rfc-2005-default-binding-mode/ref-region.rs
new file mode 100644
index 00000000000..b74e45c9328
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2005-default-binding-mode/ref-region.rs
@@ -0,0 +1,16 @@
+// run-pass
+fn foo<'a, 'b>(x: &'a &'b Option<u32>) -> &'a u32 {
+    let x: &'a &'a Option<u32> = x;
+    match x {
+        Some(r) => {
+            let _: &u32 = r;
+            r
+        },
+        &None => panic!(),
+    }
+}
+
+pub fn main() {
+    let x = Some(5);
+    foo(&&x);
+}
diff --git a/tests/ui/rfcs/rfc-2005-default-binding-mode/reset-mode.rs b/tests/ui/rfcs/rfc-2005-default-binding-mode/reset-mode.rs
new file mode 100644
index 00000000000..3b9d07610d2
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2005-default-binding-mode/reset-mode.rs
@@ -0,0 +1,14 @@
+// run-pass
+// Test that we "reset" the mode as we pass through a `&` pattern.
+//
+// cc #46688
+
+fn surprise(x: i32) {
+    assert_eq!(x, 2);
+}
+
+fn main() {
+    let x = &(1, &2);
+    let (_, &b) = x;
+    surprise(b);
+}
diff --git a/tests/ui/rfcs/rfc-2005-default-binding-mode/slice.rs b/tests/ui/rfcs/rfc-2005-default-binding-mode/slice.rs
new file mode 100644
index 00000000000..33229a205f4
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2005-default-binding-mode/slice.rs
@@ -0,0 +1,25 @@
+// run-pass
+
+fn slice_pat() {
+    let sl: &[u8] = b"foo";
+
+    match sl {
+        [first, remainder @ ..] => {
+            let _: &u8 = first;
+            assert_eq!(first, &b'f');
+            assert_eq!(remainder, b"oo");
+        }
+        [] => panic!(),
+    }
+}
+
+fn slice_pat_omission() {
+     match &[0, 1, 2] {
+        [..] => {}
+     };
+}
+
+fn main() {
+    slice_pat();
+    slice_pat_omission();
+}
diff --git a/tests/ui/rfcs/rfc-2005-default-binding-mode/struct.rs b/tests/ui/rfcs/rfc-2005-default-binding-mode/struct.rs
new file mode 100644
index 00000000000..5a00e5b6823
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2005-default-binding-mode/struct.rs
@@ -0,0 +1,22 @@
+// run-pass
+#[derive(Debug, PartialEq)]
+struct Foo {
+    x: u8,
+}
+
+pub fn main() {
+    let mut foo = Foo {
+        x: 1,
+    };
+
+    match &mut foo {
+        Foo{x: n} => {
+            *n += 1;
+        },
+    };
+
+    assert_eq!(foo, Foo{x: 2});
+
+    let Foo{x: n} = &foo;
+    assert_eq!(*n, 2);
+}
diff --git a/tests/ui/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs b/tests/ui/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs
new file mode 100644
index 00000000000..0cf9ba1b4ca
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs
@@ -0,0 +1,19 @@
+// run-pass
+#![allow(dead_code)]
+enum Foo {
+    Bar(Option<i8>, (), (), Vec<i32>),
+    Baz,
+}
+
+pub fn main() {
+    let foo = Foo::Bar(Some(1), (), (), vec![2, 3]);
+
+    match &foo {
+        Foo::Baz => panic!(),
+        Foo::Bar(None, ..) => panic!(),
+        Foo::Bar(Some(n), .., v) => {
+            assert_eq!((*v).len(), 2);
+            assert_eq!(*n, 1);
+        }
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2005-default-binding-mode/tuple.rs b/tests/ui/rfcs/rfc-2005-default-binding-mode/tuple.rs
new file mode 100644
index 00000000000..4c22aa2d718
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2005-default-binding-mode/tuple.rs
@@ -0,0 +1,12 @@
+// run-pass
+pub fn main() {
+    let foo = (Some(1), (), (), vec![2, 3]);
+
+    match &foo {
+        (Some(n), .., v) => {
+            assert_eq!((*v).len(), 2);
+            assert_eq!(*n, 1);
+        }
+        (None, (), (), ..) => panic!(),
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2151-raw-identifiers/attr.rs b/tests/ui/rfcs/rfc-2151-raw-identifiers/attr.rs
new file mode 100644
index 00000000000..d359067f627
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2151-raw-identifiers/attr.rs
@@ -0,0 +1,15 @@
+// run-pass
+use std::mem;
+
+#[r#repr(r#C, r#packed)]
+struct Test {
+    a: bool, b: u64
+}
+
+#[r#derive(r#Debug)]
+struct Test2(#[allow(unused_tuple_struct_fields)] u32);
+
+pub fn main() {
+    assert_eq!(mem::size_of::<Test>(), 9);
+    assert_eq!("Test2(123)", format!("{:?}", Test2(123)));
+}
diff --git a/tests/ui/rfcs/rfc-2151-raw-identifiers/basic.rs b/tests/ui/rfcs/rfc-2151-raw-identifiers/basic.rs
new file mode 100644
index 00000000000..f2fe59668da
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2151-raw-identifiers/basic.rs
@@ -0,0 +1,20 @@
+// run-pass
+fn r#fn(r#match: u32) -> u32 {
+    r#match
+}
+
+pub fn main() {
+    let r#struct = 1;
+    assert_eq!(1, r#struct);
+
+    let foo = 2;
+    assert_eq!(2, r#foo);
+
+    let r#bar = 3;
+    assert_eq!(3, bar);
+
+    assert_eq!(4, r#fn(4));
+
+    let r#true = false;
+    assert_eq!(r#true, false);
+}
diff --git a/tests/ui/rfcs/rfc-2151-raw-identifiers/items.rs b/tests/ui/rfcs/rfc-2151-raw-identifiers/items.rs
new file mode 100644
index 00000000000..4665225178c
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2151-raw-identifiers/items.rs
@@ -0,0 +1,32 @@
+// run-pass
+#[derive(Debug, PartialEq, Eq)]
+struct IntWrapper(u32);
+
+#[derive(Debug, Ord, PartialOrd, PartialEq, Eq, Hash, Copy, Clone, Default)]
+struct HasKeywordField {
+    r#struct: u32,
+}
+
+struct Generic<r#T>(T);
+
+trait Trait {
+    fn r#trait(&self) -> u32;
+}
+impl Trait for Generic<u32> {
+    fn r#trait(&self) -> u32 {
+        self.0
+    }
+}
+
+pub fn main() {
+    assert_eq!(IntWrapper(1), r#IntWrapper(1));
+
+    match IntWrapper(2) {
+        r#IntWrapper(r#struct) => assert_eq!(2, r#struct),
+    }
+
+    assert_eq!("HasKeywordField { struct: 3 }", format!("{:?}", HasKeywordField { r#struct: 3 }));
+
+    assert_eq!(4, Generic(4).0);
+    assert_eq!(5, Generic(5).r#trait());
+}
diff --git a/tests/ui/rfcs/rfc-2151-raw-identifiers/macros.rs b/tests/ui/rfcs/rfc-2151-raw-identifiers/macros.rs
new file mode 100644
index 00000000000..0ab7e17f87b
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2151-raw-identifiers/macros.rs
@@ -0,0 +1,38 @@
+// run-pass
+#![feature(decl_macro)]
+
+macro_rules! r#struct {
+    ($r#struct:expr) => { $r#struct }
+}
+
+macro_rules! old_macro {
+    ($a:expr) => {$a}
+}
+
+macro r#decl_macro($r#fn:expr) {
+    $r#fn
+}
+
+macro passthrough($id:ident) {
+    $id
+}
+
+macro_rules! test_pat_match {
+    (a) => { 6 };
+    (r#a) => { 7 };
+}
+
+pub fn main() {
+    r#println!("{struct}", r#struct = 1);
+    assert_eq!(2, r#struct!(2));
+    assert_eq!(3, r#old_macro!(3));
+    assert_eq!(4, decl_macro!(4));
+
+    let r#match = 5;
+    assert_eq!(5, passthrough!(r#match));
+
+    assert_eq!("r#struct", stringify!(r#struct));
+
+    assert_eq!(6, test_pat_match!(a));
+    assert_eq!(7, test_pat_match!(r#a));
+}
diff --git a/tests/ui/rfcs/rfc-2175-or-if-while-let/basic.rs b/tests/ui/rfcs/rfc-2175-or-if-while-let/basic.rs
new file mode 100644
index 00000000000..22f04c58f3b
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2175-or-if-while-let/basic.rs
@@ -0,0 +1,33 @@
+// run-pass
+#![allow(dead_code)]
+
+enum E {
+    V(u8),
+    U(u8),
+    W,
+}
+use E::*;
+
+fn main() {
+    let mut e = V(10);
+
+    if let V(x) | U(x) = e {
+        assert_eq!(x, 10);
+    }
+    while let V(x) | U(x) = e {
+        assert_eq!(x, 10);
+        e = W;
+    }
+
+    // Accept leading `|`:
+
+    let mut e = V(10);
+
+    if let | V(x) | U(x) = e {
+        assert_eq!(x, 10);
+    }
+    while let | V(x) | U(x) = e {
+        assert_eq!(x, 10);
+        e = W;
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2302-self-struct-ctor.rs b/tests/ui/rfcs/rfc-2302-self-struct-ctor.rs
new file mode 100644
index 00000000000..1ec20c50034
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2302-self-struct-ctor.rs
@@ -0,0 +1,127 @@
+// run-pass
+
+#![allow(dead_code)]
+
+use std::fmt::Display;
+
+struct ST1(i32, i32);
+
+impl ST1 {
+    fn new() -> Self {
+        ST1(0, 1)
+    }
+
+    fn ctor() -> Self {
+        Self(1,2)         // Self as a constructor
+    }
+
+    fn pattern(self) {
+        match self {
+            Self(x, y) => println!("{} {}", x, y), // Self as a pattern
+        }
+    }
+}
+
+struct ST2<T>(T); // With type parameter
+
+impl<T> ST2<T> where T: Display {
+
+    fn ctor(v: T) -> Self {
+        Self(v)
+    }
+
+    fn pattern(&self) {
+        match self {
+            Self(ref v) => println!("{}", v),
+        }
+    }
+}
+
+struct ST3<'a>(&'a i32); // With lifetime parameter
+
+impl<'a> ST3<'a> {
+
+    fn ctor(v: &'a i32) -> Self {
+        Self(v)
+    }
+
+    fn pattern(self) {
+        let Self(ref v) = self;
+        println!("{}", v);
+    }
+}
+
+struct ST4(usize);
+
+impl ST4 {
+    fn map(opt: Option<usize>) -> Option<Self> {
+        opt.map(Self)     // use `Self` as a function passed somewhere
+    }
+}
+
+struct ST5;               // unit struct
+
+impl ST5 {
+    fn ctor() -> Self {
+        Self               // `Self` as a unit struct value
+    }
+
+    fn pattern(self) -> Self {
+        match self {
+            Self => Self,   // `Self` as a unit struct value for matching
+        }
+    }
+}
+
+struct ST6(i32);
+type T = ST6;
+impl T {
+    fn ctor() -> Self {
+        ST6(1)
+    }
+
+    fn type_alias(self) {
+        let Self(_x) = match self { Self(x) => Self(x) };
+        let _opt: Option<Self> = Some(0).map(Self);
+    }
+}
+
+struct ST7<T1, T2>(T1, T2);
+
+impl ST7<i32, usize> {
+
+    fn ctor() -> Self {
+        Self(1, 2)
+    }
+
+    fn pattern(self) -> Self {
+        match self {
+            Self(x, y) => Self(x, y),
+        }
+    }
+}
+
+fn main() {
+    let v1 = ST1::ctor();
+    v1.pattern();
+
+    let v2 = ST2::ctor(10);
+    v2.pattern();
+
+    let local = 42;
+    let v3 = ST3::ctor(&local);
+    v3.pattern();
+
+    let v4 = Some(1usize);
+    let _ = ST4::map(v4);
+
+    let v5 = ST5::ctor();
+    v5.pattern();
+
+    let v6 = ST6::ctor();
+    v6.type_alias();
+
+    let v7 = ST7::<i32, usize>::ctor();
+    let r = v7.pattern();
+    println!("{} {}", r.0, r.1)
+}
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/check-pass.rs b/tests/ui/rfcs/rfc-2396-target_feature-11/check-pass.rs
new file mode 100644
index 00000000000..e0842bfa4cd
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/check-pass.rs
@@ -0,0 +1,52 @@
+// Tests the new rules added by RFC 2396, including:
+// - applying `#[target_feature]` to safe functions is allowed
+// - calling functions with `#[target_feature]` is allowed in
+//   functions which have (at least) the same features
+// - calling functions with `#[target_feature]` is allowed in
+//   unsafe contexts
+// - functions with `#[target_feature]` can coerce to unsafe fn pointers
+
+// check-pass
+// only-x86_64
+// revisions: mir thir
+// [thir]compile-flags: -Z thir-unsafeck
+
+#![feature(target_feature_11)]
+
+#[target_feature(enable = "sse2")]
+const fn sse2() {}
+
+#[cfg(target_feature = "sse2")]
+const SSE2_ONLY: () = unsafe {
+    sse2();
+};
+
+#[target_feature(enable = "sse2")]
+fn also_sse2() {
+    sse2();
+}
+
+#[target_feature(enable = "sse2")]
+#[target_feature(enable = "avx")]
+fn sse2_and_avx() {
+    sse2();
+}
+
+struct Foo;
+
+impl Foo {
+    #[target_feature(enable = "sse2")]
+    fn sse2(&self) {
+        sse2();
+    }
+}
+
+fn main() {
+    if cfg!(target_feature = "sse2") {
+        unsafe {
+            sse2();
+            Foo.sse2();
+        }
+    }
+    let sse2_ptr: unsafe fn() = sse2;
+}
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/closures-inherit-target_feature.rs b/tests/ui/rfcs/rfc-2396-target_feature-11/closures-inherit-target_feature.rs
new file mode 100644
index 00000000000..a59d7c2d784
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/closures-inherit-target_feature.rs
@@ -0,0 +1,20 @@
+// Tests #73631: closures inherit `#[target_feature]` annotations
+
+// check-pass
+// revisions: mir thir
+// [thir]compile-flags: -Z thir-unsafeck
+// only-x86_64
+
+#![feature(target_feature_11)]
+
+#[target_feature(enable="avx")]
+fn also_use_avx() {
+    println!("Hello from AVX")
+}
+
+#[target_feature(enable="avx")]
+fn use_avx() -> Box<dyn Fn()> {
+    Box::new(|| also_use_avx())
+}
+
+fn main() {}
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/feature-gate-target_feature_11.rs b/tests/ui/rfcs/rfc-2396-target_feature-11/feature-gate-target_feature_11.rs
new file mode 100644
index 00000000000..975d7a1f694
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/feature-gate-target_feature_11.rs
@@ -0,0 +1,6 @@
+// only-x86_64
+
+#[target_feature(enable = "sse2")] //~ ERROR can only be applied to `unsafe` functions
+fn foo() {}
+
+fn main() {}
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/feature-gate-target_feature_11.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/feature-gate-target_feature_11.stderr
new file mode 100644
index 00000000000..18917fd2556
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/feature-gate-target_feature_11.stderr
@@ -0,0 +1,14 @@
+error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions
+  --> $DIR/feature-gate-target_feature_11.rs:3:1
+   |
+LL | #[target_feature(enable = "sse2")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | fn foo() {}
+   | -------- not an `unsafe` function
+   |
+   = note: see issue #69098 <https://github.com/rust-lang/rust/issues/69098> for more information
+   = help: add `#![feature(target_feature_11)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.mir.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.mir.stderr
new file mode 100644
index 00000000000..cf5815df56e
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.mir.stderr
@@ -0,0 +1,18 @@
+error[E0308]: mismatched types
+  --> $DIR/fn-ptr.rs:11:21
+   |
+LL | #[target_feature(enable = "sse2")]
+   | ---------------------------------- `#[target_feature]` added here
+...
+LL |     let foo: fn() = foo;
+   |              ----   ^^^ cannot coerce functions with `#[target_feature]` to safe function pointers
+   |              |
+   |              expected due to this
+   |
+   = note: expected fn pointer `fn()`
+                 found fn item `fn() {foo}`
+   = note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.rs b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.rs
new file mode 100644
index 00000000000..c95d4a08e48
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.rs
@@ -0,0 +1,12 @@
+// revisions: mir thir
+// [thir]compile-flags: -Z thir-unsafeck
+// only-x86_64
+
+#![feature(target_feature_11)]
+
+#[target_feature(enable = "sse2")]
+fn foo() {}
+
+fn main() {
+    let foo: fn() = foo; //~ ERROR mismatched types
+}
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.thir.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.thir.stderr
new file mode 100644
index 00000000000..cf5815df56e
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.thir.stderr
@@ -0,0 +1,18 @@
+error[E0308]: mismatched types
+  --> $DIR/fn-ptr.rs:11:21
+   |
+LL | #[target_feature(enable = "sse2")]
+   | ---------------------------------- `#[target_feature]` added here
+...
+LL |     let foo: fn() = foo;
+   |              ----   ^^^ cannot coerce functions with `#[target_feature]` to safe function pointers
+   |              |
+   |              expected due to this
+   |
+   = note: expected fn pointer `fn()`
+                 found fn item `fn() {foo}`
+   = note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs
new file mode 100644
index 00000000000..43bda49624e
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs
@@ -0,0 +1,34 @@
+// only-x86_64
+
+#![feature(target_feature_11)]
+
+#[target_feature(enable = "avx")]
+fn foo() {}
+
+#[target_feature(enable = "avx")]
+unsafe fn foo_unsafe() {}
+
+fn call(f: impl Fn()) {
+    f()
+}
+
+fn call_mut(f: impl FnMut()) {
+    f()
+}
+
+fn call_once(f: impl FnOnce()) {
+    f()
+}
+
+fn main() {
+    call(foo); //~ ERROR expected a `Fn<()>` closure, found `fn() {foo}`
+    call_mut(foo); //~ ERROR expected a `FnMut<()>` closure, found `fn() {foo}`
+    call_once(foo); //~ ERROR expected a `FnOnce<()>` closure, found `fn() {foo}`
+
+    call(foo_unsafe);
+    //~^ ERROR expected a `Fn<()>` closure, found `unsafe fn() {foo_unsafe}`
+    call_mut(foo_unsafe);
+    //~^ ERROR expected a `FnMut<()>` closure, found `unsafe fn() {foo_unsafe}`
+    call_once(foo_unsafe);
+    //~^ ERROR expected a `FnOnce<()>` closure, found `unsafe fn() {foo_unsafe}`
+}
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr
new file mode 100644
index 00000000000..fc7bf22775d
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr
@@ -0,0 +1,105 @@
+error[E0277]: expected a `Fn<()>` closure, found `fn() {foo}`
+  --> $DIR/fn-traits.rs:24:10
+   |
+LL |     call(foo);
+   |     ---- ^^^ expected an `Fn<()>` closure, found `fn() {foo}`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = help: the trait `Fn<()>` is not implemented for fn item `fn() {foo}`
+   = note: wrap the `fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
+   = note: `#[target_feature]` functions do not implement the `Fn` traits
+note: required by a bound in `call`
+  --> $DIR/fn-traits.rs:11:17
+   |
+LL | fn call(f: impl Fn()) {
+   |                 ^^^^ required by this bound in `call`
+
+error[E0277]: expected a `FnMut<()>` closure, found `fn() {foo}`
+  --> $DIR/fn-traits.rs:25:14
+   |
+LL |     call_mut(foo);
+   |     -------- ^^^ expected an `FnMut<()>` closure, found `fn() {foo}`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = help: the trait `FnMut<()>` is not implemented for fn item `fn() {foo}`
+   = note: wrap the `fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
+   = note: `#[target_feature]` functions do not implement the `Fn` traits
+note: required by a bound in `call_mut`
+  --> $DIR/fn-traits.rs:15:21
+   |
+LL | fn call_mut(f: impl FnMut()) {
+   |                     ^^^^^^^ required by this bound in `call_mut`
+
+error[E0277]: expected a `FnOnce<()>` closure, found `fn() {foo}`
+  --> $DIR/fn-traits.rs:26:15
+   |
+LL |     call_once(foo);
+   |     --------- ^^^ expected an `FnOnce<()>` closure, found `fn() {foo}`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = help: the trait `FnOnce<()>` is not implemented for fn item `fn() {foo}`
+   = note: wrap the `fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
+   = note: `#[target_feature]` functions do not implement the `Fn` traits
+note: required by a bound in `call_once`
+  --> $DIR/fn-traits.rs:19:22
+   |
+LL | fn call_once(f: impl FnOnce()) {
+   |                      ^^^^^^^^ required by this bound in `call_once`
+
+error[E0277]: expected a `Fn<()>` closure, found `unsafe fn() {foo_unsafe}`
+  --> $DIR/fn-traits.rs:28:10
+   |
+LL |     call(foo_unsafe);
+   |     ---- ^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = help: the trait `Fn<()>` is not implemented for fn item `unsafe fn() {foo_unsafe}`
+   = note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }`
+   = note: `#[target_feature]` functions do not implement the `Fn` traits
+note: required by a bound in `call`
+  --> $DIR/fn-traits.rs:11:17
+   |
+LL | fn call(f: impl Fn()) {
+   |                 ^^^^ required by this bound in `call`
+
+error[E0277]: expected a `FnMut<()>` closure, found `unsafe fn() {foo_unsafe}`
+  --> $DIR/fn-traits.rs:30:14
+   |
+LL |     call_mut(foo_unsafe);
+   |     -------- ^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = help: the trait `FnMut<()>` is not implemented for fn item `unsafe fn() {foo_unsafe}`
+   = note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }`
+   = note: `#[target_feature]` functions do not implement the `Fn` traits
+note: required by a bound in `call_mut`
+  --> $DIR/fn-traits.rs:15:21
+   |
+LL | fn call_mut(f: impl FnMut()) {
+   |                     ^^^^^^^ required by this bound in `call_mut`
+
+error[E0277]: expected a `FnOnce<()>` closure, found `unsafe fn() {foo_unsafe}`
+  --> $DIR/fn-traits.rs:32:15
+   |
+LL |     call_once(foo_unsafe);
+   |     --------- ^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = help: the trait `FnOnce<()>` is not implemented for fn item `unsafe fn() {foo_unsafe}`
+   = note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }`
+   = note: `#[target_feature]` functions do not implement the `Fn` traits
+note: required by a bound in `call_once`
+  --> $DIR/fn-traits.rs:19:22
+   |
+LL | fn call_once(f: impl FnOnce()) {
+   |                      ^^^^^^^^ required by this bound in `call_once`
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/issue-99876.rs b/tests/ui/rfcs/rfc-2396-target_feature-11/issue-99876.rs
new file mode 100644
index 00000000000..033dcdfc08d
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/issue-99876.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+#![feature(target_feature_11)]
+
+struct S<T>(T)
+where
+    [T; (|| {}, 1).1]: Copy;
+
+fn main() {}
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.mir.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.mir.stderr
new file mode 100644
index 00000000000..0ef7b8b09f1
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.mir.stderr
@@ -0,0 +1,83 @@
+error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+  --> $DIR/safe-calls.rs:23:5
+   |
+LL |     sse2();
+   |     ^^^^^^ call to function with `#[target_feature]`
+   |
+   = note: can only be called if the required target features are available
+
+error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+  --> $DIR/safe-calls.rs:26:5
+   |
+LL |     avx_bmi2();
+   |     ^^^^^^^^^^ call to function with `#[target_feature]`
+   |
+   = note: can only be called if the required target features are available
+
+error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+  --> $DIR/safe-calls.rs:29:5
+   |
+LL |     Quux.avx_bmi2();
+   |     ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
+   |
+   = note: can only be called if the required target features are available
+
+error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+  --> $DIR/safe-calls.rs:36:5
+   |
+LL |     avx_bmi2();
+   |     ^^^^^^^^^^ call to function with `#[target_feature]`
+   |
+   = note: can only be called if the required target features are available
+
+error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+  --> $DIR/safe-calls.rs:39:5
+   |
+LL |     Quux.avx_bmi2();
+   |     ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
+   |
+   = note: can only be called if the required target features are available
+
+error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+  --> $DIR/safe-calls.rs:46:5
+   |
+LL |     sse2();
+   |     ^^^^^^ call to function with `#[target_feature]`
+   |
+   = note: can only be called if the required target features are available
+
+error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+  --> $DIR/safe-calls.rs:49:5
+   |
+LL |     avx_bmi2();
+   |     ^^^^^^^^^^ call to function with `#[target_feature]`
+   |
+   = note: can only be called if the required target features are available
+
+error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+  --> $DIR/safe-calls.rs:52:5
+   |
+LL |     Quux.avx_bmi2();
+   |     ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
+   |
+   = note: can only be called if the required target features are available
+
+error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+  --> $DIR/safe-calls.rs:60:5
+   |
+LL |     sse2();
+   |     ^^^^^^ call to function with `#[target_feature]`
+   |
+   = note: can only be called if the required target features are available
+
+error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
+  --> $DIR/safe-calls.rs:65:18
+   |
+LL | const name: () = sse2();
+   |                  ^^^^^^ call to function with `#[target_feature]`
+   |
+   = note: can only be called if the required target features are available
+
+error: aborting due to 10 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs
new file mode 100644
index 00000000000..cebc6f94784
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs
@@ -0,0 +1,69 @@
+// revisions: mir thir
+// [thir]compile-flags: -Z thir-unsafeck
+// only-x86_64
+
+#![feature(target_feature_11)]
+
+#[target_feature(enable = "sse2")]
+const fn sse2() {}
+
+#[target_feature(enable = "avx")]
+#[target_feature(enable = "bmi2")]
+fn avx_bmi2() {}
+
+struct Quux;
+
+impl Quux {
+    #[target_feature(enable = "avx")]
+    #[target_feature(enable = "bmi2")]
+    fn avx_bmi2(&self) {}
+}
+
+fn foo() {
+    sse2();
+    //[mir]~^ ERROR call to function with `#[target_feature]` is unsafe
+    //[thir]~^^ ERROR call to function `sse2` with `#[target_feature]` is unsafe
+    avx_bmi2();
+    //[mir]~^ ERROR call to function with `#[target_feature]` is unsafe
+    //[thir]~^^ ERROR call to function `avx_bmi2` with `#[target_feature]` is unsafe
+    Quux.avx_bmi2();
+    //[mir]~^ ERROR call to function with `#[target_feature]` is unsafe
+    //[thir]~^^ ERROR call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe
+}
+
+#[target_feature(enable = "sse2")]
+fn bar() {
+    avx_bmi2();
+    //[mir]~^ ERROR call to function with `#[target_feature]` is unsafe
+    //[thir]~^^ ERROR call to function `avx_bmi2` with `#[target_feature]` is unsafe
+    Quux.avx_bmi2();
+    //[mir]~^ ERROR call to function with `#[target_feature]` is unsafe
+    //[thir]~^^ ERROR call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe
+}
+
+#[target_feature(enable = "avx")]
+fn baz() {
+    sse2();
+    //[mir]~^ ERROR call to function with `#[target_feature]` is unsafe
+    //[thir]~^^ ERROR call to function `sse2` with `#[target_feature]` is unsafe
+    avx_bmi2();
+    //[mir]~^ ERROR call to function with `#[target_feature]` is unsafe
+    //[thir]~^^ ERROR call to function `avx_bmi2` with `#[target_feature]` is unsafe
+    Quux.avx_bmi2();
+    //[mir]~^ ERROR call to function with `#[target_feature]` is unsafe
+    //[thir]~^^ ERROR call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe
+}
+
+#[target_feature(enable = "avx")]
+#[target_feature(enable = "bmi2")]
+fn qux() {
+    sse2();
+    //[mir]~^ ERROR call to function with `#[target_feature]` is unsafe
+    //[thir]~^^ ERROR call to function `sse2` with `#[target_feature]` is unsafe
+}
+
+const name: () = sse2();
+//[mir]~^ ERROR call to function with `#[target_feature]` is unsafe
+//[thir]~^^ ERROR call to function `sse2` with `#[target_feature]` is unsafe
+
+fn main() {}
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.thir.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.thir.stderr
new file mode 100644
index 00000000000..c75ac6e8b9a
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.thir.stderr
@@ -0,0 +1,83 @@
+error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
+  --> $DIR/safe-calls.rs:23:5
+   |
+LL |     sse2();
+   |     ^^^^^^ call to function with `#[target_feature]`
+   |
+   = note: can only be called if the required target features are available
+
+error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
+  --> $DIR/safe-calls.rs:26:5
+   |
+LL |     avx_bmi2();
+   |     ^^^^^^^^^^ call to function with `#[target_feature]`
+   |
+   = note: can only be called if the required target features are available
+
+error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
+  --> $DIR/safe-calls.rs:29:5
+   |
+LL |     Quux.avx_bmi2();
+   |     ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
+   |
+   = note: can only be called if the required target features are available
+
+error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
+  --> $DIR/safe-calls.rs:36:5
+   |
+LL |     avx_bmi2();
+   |     ^^^^^^^^^^ call to function with `#[target_feature]`
+   |
+   = note: can only be called if the required target features are available
+
+error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
+  --> $DIR/safe-calls.rs:39:5
+   |
+LL |     Quux.avx_bmi2();
+   |     ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
+   |
+   = note: can only be called if the required target features are available
+
+error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
+  --> $DIR/safe-calls.rs:46:5
+   |
+LL |     sse2();
+   |     ^^^^^^ call to function with `#[target_feature]`
+   |
+   = note: can only be called if the required target features are available
+
+error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
+  --> $DIR/safe-calls.rs:49:5
+   |
+LL |     avx_bmi2();
+   |     ^^^^^^^^^^ call to function with `#[target_feature]`
+   |
+   = note: can only be called if the required target features are available
+
+error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
+  --> $DIR/safe-calls.rs:52:5
+   |
+LL |     Quux.avx_bmi2();
+   |     ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
+   |
+   = note: can only be called if the required target features are available
+
+error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
+  --> $DIR/safe-calls.rs:60:5
+   |
+LL |     sse2();
+   |     ^^^^^^ call to function with `#[target_feature]`
+   |
+   = note: can only be called if the required target features are available
+
+error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block
+  --> $DIR/safe-calls.rs:65:18
+   |
+LL | const name: () = sse2();
+   |                  ^^^^^^ call to function with `#[target_feature]`
+   |
+   = note: can only be called if the required target features are available
+
+error: aborting due to 10 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.rs b/tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.rs
new file mode 100644
index 00000000000..7314fa8cced
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.rs
@@ -0,0 +1,21 @@
+// only-x86_64
+
+#![feature(target_feature_11)]
+
+trait Foo {
+    fn foo(&self);
+    unsafe fn unsf_foo(&self);
+}
+
+struct Bar;
+
+impl Foo for Bar {
+    #[target_feature(enable = "sse2")]
+    //~^ ERROR cannot be applied to safe trait method
+    fn foo(&self) {}
+
+    #[target_feature(enable = "sse2")]
+    unsafe fn unsf_foo(&self) {}
+}
+
+fn main() {}
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.stderr
new file mode 100644
index 00000000000..07d6e090059
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.stderr
@@ -0,0 +1,11 @@
+error: `#[target_feature(..)]` cannot be applied to safe trait method
+  --> $DIR/trait-impl.rs:13:5
+   |
+LL |     #[target_feature(enable = "sse2")]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be applied to safe trait method
+LL |
+LL |     fn foo(&self) {}
+   |     ------------- not an `unsafe` function
+
+error: aborting due to previous error
+
diff --git a/tests/ui/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs b/tests/ui/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs
new file mode 100644
index 00000000000..6d7bca4da24
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs
@@ -0,0 +1,15 @@
+// run-pass
+#![allow(dead_code)]
+#![allow(unused_variables)]
+// Test that removed keywords are allowed as identifiers.
+fn main () {
+    let offsetof = ();
+    let alignof = ();
+    let sizeof = ();
+    let pure = ();
+}
+
+fn offsetof() {}
+fn alignof() {}
+fn sizeof() {}
+fn pure() {}
diff --git a/tests/ui/rfcs/rfc-2528-type-changing-struct-update/coerce-in-base-expr.rs b/tests/ui/rfcs/rfc-2528-type-changing-struct-update/coerce-in-base-expr.rs
new file mode 100644
index 00000000000..75e48bf4a48
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2528-type-changing-struct-update/coerce-in-base-expr.rs
@@ -0,0 +1,28 @@
+// check-pass
+
+#![feature(type_changing_struct_update)]
+#![allow(incomplete_features)]
+
+use std::any::Any;
+
+struct Foo<A, B: ?Sized, C: ?Sized> {
+    a: A,
+    b: Box<B>,
+    c: Box<C>,
+}
+
+struct B;
+struct C;
+
+fn main() {
+    let y = Foo::<usize, dyn Any, dyn Any> {
+        a: 0,
+        b: Box::new(B),
+        ..Foo {
+            a: 0,
+            b: Box::new(B),
+            // C needs to be told to coerce to `Box<dyn Any>`
+            c: Box::new(C),
+        }
+    };
+}
diff --git a/tests/ui/rfcs/rfc-2528-type-changing-struct-update/feature-gate.rs b/tests/ui/rfcs/rfc-2528-type-changing-struct-update/feature-gate.rs
new file mode 100644
index 00000000000..1e8b99ba564
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2528-type-changing-struct-update/feature-gate.rs
@@ -0,0 +1,29 @@
+// gate-test-type_changing_struct_update
+
+#[derive(Debug)]
+struct Machine<S> {
+    state: S,
+    common_field1: &'static str,
+    common_field2: i32,
+}
+#[derive(Debug)]
+struct State1;
+#[derive(Debug, PartialEq)]
+struct State2;
+
+fn update_to_state2() {
+    let m1: Machine<State1> = Machine {
+        state: State1,
+        common_field1: "hello",
+        common_field2: 2,
+    };
+    let m2: Machine<State2> = Machine {
+        state: State2,
+        ..m1
+        //~^ ERROR type changing struct updating is experimental [E0658]
+        //~| ERROR mismatched types [E0308]
+    };
+    assert_eq!(State2, m2.state);
+}
+
+fn main() {}
diff --git a/tests/ui/rfcs/rfc-2528-type-changing-struct-update/feature-gate.stderr b/tests/ui/rfcs/rfc-2528-type-changing-struct-update/feature-gate.stderr
new file mode 100644
index 00000000000..2217b8c0498
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2528-type-changing-struct-update/feature-gate.stderr
@@ -0,0 +1,22 @@
+error[E0658]: type changing struct updating is experimental
+  --> $DIR/feature-gate.rs:22:11
+   |
+LL |         ..m1
+   |           ^^
+   |
+   = note: see issue #86555 <https://github.com/rust-lang/rust/issues/86555> for more information
+   = help: add `#![feature(type_changing_struct_update)]` to the crate attributes to enable
+
+error[E0308]: mismatched types
+  --> $DIR/feature-gate.rs:22:11
+   |
+LL |         ..m1
+   |           ^^ expected struct `State2`, found struct `State1`
+   |
+   = note: expected struct `Machine<State2>`
+              found struct `Machine<State1>`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0308, E0658.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/rfcs/rfc-2528-type-changing-struct-update/issue-92010-trait-bound-not-satisfied.rs b/tests/ui/rfcs/rfc-2528-type-changing-struct-update/issue-92010-trait-bound-not-satisfied.rs
new file mode 100644
index 00000000000..f1a54ee5867
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2528-type-changing-struct-update/issue-92010-trait-bound-not-satisfied.rs
@@ -0,0 +1,12 @@
+#[derive(Clone)]
+struct P<T> {
+    x: T,
+    y: f64,
+}
+
+impl<T> P<T> {
+    fn y(&self, y: f64) -> Self { P{y, .. self.clone() } }
+                                       //~^ mismatched types [E0308]
+}
+
+fn main() {}
diff --git a/tests/ui/rfcs/rfc-2528-type-changing-struct-update/issue-92010-trait-bound-not-satisfied.stderr b/tests/ui/rfcs/rfc-2528-type-changing-struct-update/issue-92010-trait-bound-not-satisfied.stderr
new file mode 100644
index 00000000000..5957ea7c9ef
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2528-type-changing-struct-update/issue-92010-trait-bound-not-satisfied.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-92010-trait-bound-not-satisfied.rs:8:43
+   |
+LL |     fn y(&self, y: f64) -> Self { P{y, .. self.clone() } }
+   |                                           ^^^^^^^^^^^^ expected struct `P`, found `&P<T>`
+   |
+   = note: expected struct `P<T>`
+           found reference `&P<T>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/rfcs/rfc-2528-type-changing-struct-update/issue-96878.rs b/tests/ui/rfcs/rfc-2528-type-changing-struct-update/issue-96878.rs
new file mode 100644
index 00000000000..3dfbef0ee90
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2528-type-changing-struct-update/issue-96878.rs
@@ -0,0 +1,31 @@
+// check-pass
+
+#![feature(type_changing_struct_update)]
+#![allow(incomplete_features)]
+
+use std::borrow::Cow;
+use std::marker::PhantomData;
+
+#[derive(Default)]
+struct NonGeneric {
+    field1: usize,
+}
+
+#[derive(Default)]
+struct Generic<T, U> {
+    field1: T,
+    field2: U,
+}
+
+#[derive(Default)]
+struct MoreGeneric<'a, const N: usize> {
+    // If only `for<const N: usize> [u32; N]: Default`...
+    field1: PhantomData<[u32; N]>,
+    field2: Cow<'a, str>,
+}
+
+fn main() {
+    let default1 = NonGeneric { ..Default::default() };
+    let default2: Generic<i32, f32> = Generic { ..Default::default() };
+    let default3: MoreGeneric<'static, 12> = MoreGeneric { ..Default::default() };
+}
diff --git a/tests/ui/rfcs/rfc-2528-type-changing-struct-update/lifetime-update.rs b/tests/ui/rfcs/rfc-2528-type-changing-struct-update/lifetime-update.rs
new file mode 100644
index 00000000000..df2fef55dd2
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2528-type-changing-struct-update/lifetime-update.rs
@@ -0,0 +1,43 @@
+#![feature(type_changing_struct_update)]
+#![allow(incomplete_features)]
+
+#[derive(Clone)]
+struct Machine<'a, S> {
+    state: S,
+    lt_str: &'a str,
+    common_field: i32,
+}
+
+#[derive(Clone)]
+struct State1;
+#[derive(Clone)]
+struct State2;
+
+fn update_to_state2() {
+    let s = String::from("hello");
+    let m1: Machine<State1> = Machine {
+        state: State1,
+        lt_str: &s,
+                //~^ ERROR `s` does not live long enough [E0597]
+                // FIXME: The error here actually comes from line 34. The
+                // span of the error message should be corrected to line 34
+        common_field: 2,
+    };
+    // update lifetime
+    let m3: Machine<'static, State1> = Machine {
+        lt_str: "hello, too",
+        ..m1.clone()
+    };
+    // update lifetime and type
+    let m4: Machine<'static, State2> = Machine {
+        state: State2,
+        lt_str: "hello, again",
+        ..m1.clone()
+    };
+    // updating to `static should fail.
+    let m2: Machine<'static, State1> = Machine {
+        ..m1
+    };
+}
+
+fn main() {}
diff --git a/tests/ui/rfcs/rfc-2528-type-changing-struct-update/lifetime-update.stderr b/tests/ui/rfcs/rfc-2528-type-changing-struct-update/lifetime-update.stderr
new file mode 100644
index 00000000000..5f93ad6e027
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2528-type-changing-struct-update/lifetime-update.stderr
@@ -0,0 +1,15 @@
+error[E0597]: `s` does not live long enough
+  --> $DIR/lifetime-update.rs:20:17
+   |
+LL |         lt_str: &s,
+   |                 ^^ borrowed value does not live long enough
+...
+LL |     let m2: Machine<'static, State1> = Machine {
+   |             ------------------------ type annotation requires that `s` is borrowed for `'static`
+...
+LL | }
+   | - `s` dropped here while still borrowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui/rfcs/rfc-2528-type-changing-struct-update/type-generic-update.rs b/tests/ui/rfcs/rfc-2528-type-changing-struct-update/type-generic-update.rs
new file mode 100644
index 00000000000..dae1241d35a
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2528-type-changing-struct-update/type-generic-update.rs
@@ -0,0 +1,56 @@
+#![feature(type_changing_struct_update)]
+#![allow(incomplete_features)]
+
+struct Machine<'a, S, M> {
+    state: S,
+    message: M,
+    lt_str: &'a str,
+    common_field: i32,
+}
+
+struct State1;
+struct State2;
+
+struct Message1;
+struct Message2;
+
+fn update() {
+    let m1: Machine<State1, Message1> = Machine {
+        state: State1,
+        message: Message1,
+        lt_str: "hello",
+        common_field: 2,
+    };
+    // single type update
+    let m2: Machine<State2, Message1> = Machine {
+        state: State2,
+        ..m1
+    };
+    // multiple type update
+    let m3: Machine<State2, Message2> = Machine {
+        state: State2,
+        message: Message2,
+        ..m1
+    };
+}
+
+fn fail_update() {
+    let m1: Machine<f64, f64> = Machine {
+        state: 3.2,
+        message: 6.4,
+        lt_str: "hello",
+        common_field: 2,
+    };
+    // single type update fail
+    let m2: Machine<i32, f64> = Machine {
+        ..m1
+        //~^ ERROR mismatched types [E0308]
+    };
+    // multiple type update fail
+    let m3 = Machine::<i32, i32> {
+        ..m1
+        //~^ ERROR mismatched types [E0308]
+    };
+}
+
+fn main() {}
diff --git a/tests/ui/rfcs/rfc-2528-type-changing-struct-update/type-generic-update.stderr b/tests/ui/rfcs/rfc-2528-type-changing-struct-update/type-generic-update.stderr
new file mode 100644
index 00000000000..6f31b1a9620
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2528-type-changing-struct-update/type-generic-update.stderr
@@ -0,0 +1,21 @@
+error[E0308]: mismatched types
+  --> $DIR/type-generic-update.rs:46:11
+   |
+LL |         ..m1
+   |           ^^ expected `i32`, found `f64`
+   |
+   = note: expected struct `Machine<'_, i32, _>`
+              found struct `Machine<'_, f64, _>`
+
+error[E0308]: mismatched types
+  --> $DIR/type-generic-update.rs:51:11
+   |
+LL |         ..m1
+   |           ^^ expected `i32`, found `f64`
+   |
+   = note: expected struct `Machine<'_, i32, i32>`
+              found struct `Machine<'_, f64, f64>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs b/tests/ui/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs
new file mode 100644
index 00000000000..17174e22c74
--- /dev/null
+++ b/tests/ui/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs
@@ -0,0 +1,23 @@
+// run-pass
+#![allow(dead_code)]
+
+macro_rules! foo {
+    (#[$attr:meta] $x:ident) => {
+        #[$attr]
+        struct $x {
+            x: u32
+        }
+    }
+}
+
+foo! { #[derive(PartialEq, Eq)] Foo }
+
+const FOO: Foo = Foo { x: 0 };
+
+fn main() {
+    let y = Foo { x: 1 };
+    match y {
+        FOO => { }
+        _ => { }
+    }
+}
diff --git a/tests/ui/rfcs/rfc1445/eq-allows-match.rs b/tests/ui/rfcs/rfc1445/eq-allows-match.rs
new file mode 100644
index 00000000000..405a69c94bf
--- /dev/null
+++ b/tests/ui/rfcs/rfc1445/eq-allows-match.rs
@@ -0,0 +1,17 @@
+// run-pass
+#![allow(dead_code)]
+
+#[derive(PartialEq, Eq)]
+struct Foo {
+    x: u32
+}
+
+const FOO: Foo = Foo { x: 0 };
+
+fn main() {
+    let y = Foo { x: 1 };
+    match y {
+        FOO => { }
+        _ => { }
+    }
+}
diff --git a/tests/ui/rfcs/rfc1623-2.rs b/tests/ui/rfcs/rfc1623-2.rs
new file mode 100644
index 00000000000..c0e13a5f5f0
--- /dev/null
+++ b/tests/ui/rfcs/rfc1623-2.rs
@@ -0,0 +1,99 @@
+#![allow(dead_code)]
+
+fn non_elidable<'a, 'b>(a: &'a u8, b: &'b u8) -> &'a u8 {
+    a
+}
+
+// The incorrect case without `for<'a>` is tested for in `rfc1623-2.rs`
+static NON_ELIDABLE_FN: &for<'a> fn(&'a u8, &'a u8) -> &'a u8 =
+    &(non_elidable as for<'a> fn(&'a u8, &'a u8) -> &'a u8);
+
+struct SomeStruct<'x, 'y, 'z: 'x> {
+    foo: &'x Foo<'z>,
+    bar: &'x Bar<'z>,
+    f: &'y dyn for<'a, 'b> Fn(&'a Foo<'b>) -> &'a Foo<'b>,
+}
+
+// Without this, the wf-check will fail early so we'll never see the
+// error in SOME_STRUCT's body.
+unsafe impl<'x, 'y, 'z: 'x> Sync for SomeStruct<'x, 'y, 'z> {}
+
+fn id<T>(t: T) -> T {
+    t
+}
+
+static SOME_STRUCT: &SomeStruct = &SomeStruct {
+    foo: &Foo { bools: &[false, true] },
+    bar: &Bar { bools: &[true, true] },
+    f: &id,
+    //~^ ERROR mismatched types
+    //~| ERROR mismatched types
+    //~| ERROR implementation of `FnOnce` is not general enough
+    //~| ERROR implementation of `FnOnce` is not general enough
+};
+
+// very simple test for a 'static static with default lifetime
+static STATIC_STR: &'static str = "&'static str";
+const CONST_STR: &'static str = "&'static str";
+
+// this should be the same as without default:
+static EXPLICIT_STATIC_STR: &'static str = "&'static str";
+const EXPLICIT_CONST_STR: &'static str = "&'static str";
+
+// a function that elides to an unbound lifetime for both in- and output
+fn id_u8_slice(arg: &[u8]) -> &[u8] {
+    arg
+}
+
+// one with a function, argument elided
+static STATIC_SIMPLE_FN: &'static fn(&[u8]) -> &[u8] = &(id_u8_slice as fn(&[u8]) -> &[u8]);
+const CONST_SIMPLE_FN: &'static fn(&[u8]) -> &[u8] = &(id_u8_slice as fn(&[u8]) -> &[u8]);
+
+// this should be the same as without elision
+static STATIC_NON_ELIDED_fN: &'static for<'a> fn(&'a [u8]) -> &'a [u8] =
+    &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]);
+const CONST_NON_ELIDED_fN: &'static for<'a> fn(&'a [u8]) -> &'a [u8] =
+    &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]);
+
+// another function that elides, each to a different unbound lifetime
+fn multi_args(a: &u8, b: &u8, c: &u8) {}
+
+static STATIC_MULTI_FN: &'static fn(&u8, &u8, &u8) = &(multi_args as fn(&u8, &u8, &u8));
+const CONST_MULTI_FN: &'static fn(&u8, &u8, &u8) = &(multi_args as fn(&u8, &u8, &u8));
+
+struct Foo<'a> {
+    bools: &'a [bool],
+}
+
+static STATIC_FOO: Foo<'static> = Foo { bools: &[true, false] };
+const CONST_FOO: Foo<'static> = Foo { bools: &[true, false] };
+
+type Bar<'a> = Foo<'a>;
+
+static STATIC_BAR: Bar<'static> = Bar { bools: &[true, false] };
+const CONST_BAR: Bar<'static> = Bar { bools: &[true, false] };
+
+type Baz<'a> = fn(&'a [u8]) -> Option<u8>;
+
+fn baz(e: &[u8]) -> Option<u8> {
+    e.first().map(|x| *x)
+}
+
+static STATIC_BAZ: &'static Baz<'static> = &(baz as Baz);
+const CONST_BAZ: &'static Baz<'static> = &(baz as Baz);
+
+static BYTES: &'static [u8] = &[1, 2, 3];
+
+fn main() {
+    let x = &[1u8, 2, 3];
+    let y = x;
+
+    // this works, so lifetime < `'static` is valid
+    assert_eq!(Some(1), STATIC_BAZ(y));
+    assert_eq!(Some(1), CONST_BAZ(y));
+
+    let y = &[1u8, 2, 3];
+
+    STATIC_BAZ(BYTES); // BYTES has static lifetime
+    CONST_BAZ(y); // interestingly this does not get reported
+}
diff --git a/tests/ui/rfcs/rfc1623-2.stderr b/tests/ui/rfcs/rfc1623-2.stderr
new file mode 100644
index 00000000000..d183eaaa623
--- /dev/null
+++ b/tests/ui/rfcs/rfc1623-2.stderr
@@ -0,0 +1,39 @@
+error[E0308]: mismatched types
+  --> $DIR/rfc1623-2.rs:28:8
+   |
+LL |     f: &id,
+   |        ^^^ one type is more general than the other
+   |
+   = note: expected trait `for<'a, 'b> Fn<(&'a Foo<'b>,)>`
+              found trait `Fn<(&Foo<'_>,)>`
+
+error[E0308]: mismatched types
+  --> $DIR/rfc1623-2.rs:28:8
+   |
+LL |     f: &id,
+   |        ^^^ one type is more general than the other
+   |
+   = note: expected trait `for<'a, 'b> Fn<(&'a Foo<'b>,)>`
+              found trait `Fn<(&Foo<'_>,)>`
+
+error: implementation of `FnOnce` is not general enough
+  --> $DIR/rfc1623-2.rs:28:8
+   |
+LL |     f: &id,
+   |        ^^^ implementation of `FnOnce` is not general enough
+   |
+   = note: `fn(&'2 Foo<'_>) -> &'2 Foo<'_> {id::<&'2 Foo<'_>>}` must implement `FnOnce<(&'1 Foo<'b>,)>`, for any lifetime `'1`...
+   = note: ...but it actually implements `FnOnce<(&'2 Foo<'_>,)>`, for some specific lifetime `'2`
+
+error: implementation of `FnOnce` is not general enough
+  --> $DIR/rfc1623-2.rs:28:8
+   |
+LL |     f: &id,
+   |        ^^^ implementation of `FnOnce` is not general enough
+   |
+   = note: `fn(&Foo<'2>) -> &Foo<'2> {id::<&Foo<'2>>}` must implement `FnOnce<(&'a Foo<'1>,)>`, for any lifetime `'1`...
+   = note: ...but it actually implements `FnOnce<(&Foo<'2>,)>`, for some specific lifetime `'2`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/rfcs/rfc1623-3.rs b/tests/ui/rfcs/rfc1623-3.rs
new file mode 100644
index 00000000000..26fa6fdb57f
--- /dev/null
+++ b/tests/ui/rfcs/rfc1623-3.rs
@@ -0,0 +1,14 @@
+#![allow(dead_code)]
+
+fn non_elidable<'a, 'b>(a: &'a u8, b: &'b u8) -> &'a u8 {
+    a
+}
+
+// the boundaries of elision
+static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 =
+//~^ ERROR missing lifetime specifier [E0106]
+    &(non_elidable as fn(&u8, &u8) -> &u8);
+    //~^ ERROR missing lifetime specifier [E0106]
+    //~| ERROR non-primitive cast
+
+fn main() {}
diff --git a/tests/ui/rfcs/rfc1623-3.stderr b/tests/ui/rfcs/rfc1623-3.stderr
new file mode 100644
index 00000000000..77fc3f0412e
--- /dev/null
+++ b/tests/ui/rfcs/rfc1623-3.stderr
@@ -0,0 +1,35 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/rfc1623-3.rs:8:42
+   |
+LL | static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 =
+   |                             ---  ---     ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2
+   = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
+help: consider making the type lifetime-generic with a new `'a` lifetime
+   |
+LL | static NON_ELIDABLE_FN: &for<'a> fn(&'a u8, &'a u8) -> &'a u8 =
+   |                          +++++++     ++      ++         ++
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/rfc1623-3.rs:10:39
+   |
+LL |     &(non_elidable as fn(&u8, &u8) -> &u8);
+   |                          ---  ---     ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2
+help: consider making the type lifetime-generic with a new `'a` lifetime
+   |
+LL |     &(non_elidable as for<'a> fn(&'a u8, &'a u8) -> &'a u8);
+   |                       +++++++     ++      ++         ++
+
+error[E0605]: non-primitive cast: `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {non_elidable}` as `for<'a, 'b> fn(&'a u8, &'b u8) -> &u8`
+  --> $DIR/rfc1623-3.rs:10:6
+   |
+LL |     &(non_elidable as fn(&u8, &u8) -> &u8);
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0106, E0605.
+For more information about an error, try `rustc --explain E0106`.
diff --git a/tests/ui/rfcs/rfc1623.rs b/tests/ui/rfcs/rfc1623.rs
new file mode 100644
index 00000000000..adaf25c6bbf
--- /dev/null
+++ b/tests/ui/rfcs/rfc1623.rs
@@ -0,0 +1,75 @@
+// run-pass
+#![allow(unused_variables)]
+#![allow(non_upper_case_globals)]
+
+#![allow(dead_code)]
+
+// very simple test for a 'static static with default lifetime
+static STATIC_STR: &str = "&'static str";
+const CONST_STR: &str = "&'static str";
+
+// this should be the same as without default:
+static EXPLICIT_STATIC_STR: &'static str = "&'static str";
+const EXPLICIT_CONST_STR: &'static str = "&'static str";
+
+// a function that elides to an unbound lifetime for both in- and output
+fn id_u8_slice(arg: &[u8]) -> &[u8] {
+    arg
+}
+
+// one with a function, argument elided
+static STATIC_SIMPLE_FN: &fn(&[u8]) -> &[u8] = &(id_u8_slice as fn(&[u8]) -> &[u8]);
+const CONST_SIMPLE_FN: &fn(&[u8]) -> &[u8] = &(id_u8_slice as fn(&[u8]) -> &[u8]);
+
+// this should be the same as without elision
+static STATIC_NON_ELIDED_fN: &for<'a> fn(&'a [u8]) -> &'a [u8] =
+    &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]);
+const CONST_NON_ELIDED_fN: &for<'a> fn(&'a [u8]) -> &'a [u8] =
+    &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]);
+
+// another function that elides, each to a different unbound lifetime
+fn multi_args(a: &u8, b: &u8, c: &u8) {}
+
+static STATIC_MULTI_FN: &fn(&u8, &u8, &u8) = &(multi_args as fn(&u8, &u8, &u8));
+const CONST_MULTI_FN: &fn(&u8, &u8, &u8) = &(multi_args as fn(&u8, &u8, &u8));
+
+struct Foo<'a> {
+    bools: &'a [bool],
+}
+
+static STATIC_FOO: Foo = Foo { bools: &[true, false] };
+const CONST_FOO: Foo = Foo { bools: &[true, false] };
+
+type Bar<'a> = Foo<'a>;
+
+static STATIC_BAR: Bar = Bar { bools: &[true, false] };
+const CONST_BAR: Bar = Bar { bools: &[true, false] };
+
+type Baz<'a> = fn(&'a [u8]) -> Option<u8>;
+
+fn baz(e: &[u8]) -> Option<u8> {
+    e.first().map(|x| *x)
+}
+
+static STATIC_BAZ: &Baz = &(baz as Baz);
+const CONST_BAZ: &Baz = &(baz as Baz);
+
+static BYTES: &[u8] = &[1, 2, 3];
+
+fn main() {
+    // make sure that the lifetime is actually elided (and not defaulted)
+    let x = &[1u8, 2, 3];
+    STATIC_SIMPLE_FN(x);
+    CONST_SIMPLE_FN(x);
+
+    STATIC_BAZ(BYTES); // neees static lifetime
+    CONST_BAZ(BYTES);
+
+    // make sure this works with different lifetimes
+    let a = &1;
+    {
+        let b = &2;
+        let c = &3;
+        CONST_MULTI_FN(a, b, c);
+    }
+}
diff --git a/tests/ui/rfcs/rfc1717/library-override.rs b/tests/ui/rfcs/rfc1717/library-override.rs
new file mode 100644
index 00000000000..014ccac31b7
--- /dev/null
+++ b/tests/ui/rfcs/rfc1717/library-override.rs
@@ -0,0 +1,14 @@
+// run-pass
+// ignore-wasm32-bare no libc to test ffi with
+// compile-flags: -lstatic=wronglibrary:rust_test_helpers
+
+#[link(name = "wronglibrary", kind = "dylib")]
+extern "C" {
+    pub fn rust_dbg_extern_identity_u32(x: u32) -> u32;
+}
+
+fn main() {
+    unsafe {
+        rust_dbg_extern_identity_u32(42);
+    }
+}
diff --git a/tests/ui/rfcs/rfc1857-drop-order.rs b/tests/ui/rfcs/rfc1857-drop-order.rs
new file mode 100644
index 00000000000..4c4816c2fbc
--- /dev/null
+++ b/tests/ui/rfcs/rfc1857-drop-order.rs
@@ -0,0 +1,224 @@
+// run-pass
+// needs-unwind
+
+#![allow(dead_code, unreachable_code)]
+
+use std::cell::RefCell;
+use std::rc::Rc;
+use std::panic::{self, AssertUnwindSafe, UnwindSafe};
+
+// This struct is used to record the order in which elements are dropped
+struct PushOnDrop {
+    vec: Rc<RefCell<Vec<u32>>>,
+    val: u32
+}
+
+impl PushOnDrop {
+    fn new(val: u32, vec: Rc<RefCell<Vec<u32>>>) -> PushOnDrop {
+        PushOnDrop { vec, val }
+    }
+}
+
+impl Drop for PushOnDrop {
+    fn drop(&mut self) {
+        self.vec.borrow_mut().push(self.val)
+    }
+}
+
+impl UnwindSafe for PushOnDrop { }
+
+// Structs
+struct TestStruct {
+    x: PushOnDrop,
+    y: PushOnDrop,
+    z: PushOnDrop
+}
+
+// Tuple structs
+struct TestTupleStruct(PushOnDrop, PushOnDrop, PushOnDrop);
+
+// Enum variants
+enum TestEnum {
+    Tuple(PushOnDrop, PushOnDrop, PushOnDrop),
+    Struct { x: PushOnDrop, y: PushOnDrop, z: PushOnDrop }
+}
+
+fn test_drop_tuple() {
+    // Tuple fields are dropped in the same order they are declared
+    let dropped_fields = Rc::new(RefCell::new(Vec::new()));
+    let test_tuple = (PushOnDrop::new(1, dropped_fields.clone()),
+                      PushOnDrop::new(2, dropped_fields.clone()));
+    drop(test_tuple);
+    assert_eq!(*dropped_fields.borrow(), &[1, 2]);
+
+    // Panic during construction means that fields are treated as local variables
+    // Therefore they are dropped in reverse order of initialization
+    let dropped_fields = Rc::new(RefCell::new(Vec::new()));
+    let cloned = AssertUnwindSafe(dropped_fields.clone());
+    panic::catch_unwind(|| {
+        (PushOnDrop::new(2, cloned.clone()),
+         PushOnDrop::new(1, cloned.clone()),
+         panic!("this panic is caught :D"));
+    }).err().unwrap();
+    assert_eq!(*dropped_fields.borrow(), &[1, 2]);
+}
+
+fn test_drop_struct() {
+    // Struct fields are dropped in the same order they are declared
+    let dropped_fields = Rc::new(RefCell::new(Vec::new()));
+    let test_struct = TestStruct {
+        x: PushOnDrop::new(1, dropped_fields.clone()),
+        y: PushOnDrop::new(2, dropped_fields.clone()),
+        z: PushOnDrop::new(3, dropped_fields.clone()),
+    };
+    drop(test_struct);
+    assert_eq!(*dropped_fields.borrow(), &[1, 2, 3]);
+
+    // The same holds for tuple structs
+    let dropped_fields = Rc::new(RefCell::new(Vec::new()));
+    let test_tuple_struct = TestTupleStruct(PushOnDrop::new(1, dropped_fields.clone()),
+                                            PushOnDrop::new(2, dropped_fields.clone()),
+                                            PushOnDrop::new(3, dropped_fields.clone()));
+    drop(test_tuple_struct);
+    assert_eq!(*dropped_fields.borrow(), &[1, 2, 3]);
+
+    // Panic during struct construction means that fields are treated as local variables
+    // Therefore they are dropped in reverse order of initialization
+    let dropped_fields = Rc::new(RefCell::new(Vec::new()));
+    let cloned = AssertUnwindSafe(dropped_fields.clone());
+    panic::catch_unwind(|| {
+        TestStruct {
+            x: PushOnDrop::new(2, cloned.clone()),
+            y: PushOnDrop::new(1, cloned.clone()),
+            z: panic!("this panic is caught :D")
+        };
+    }).err().unwrap();
+    assert_eq!(*dropped_fields.borrow(), &[1, 2]);
+
+    // Test with different initialization order
+    let dropped_fields = Rc::new(RefCell::new(Vec::new()));
+    let cloned = AssertUnwindSafe(dropped_fields.clone());
+    panic::catch_unwind(|| {
+        TestStruct {
+            y: PushOnDrop::new(2, cloned.clone()),
+            x: PushOnDrop::new(1, cloned.clone()),
+            z: panic!("this panic is caught :D")
+        };
+    }).err().unwrap();
+    assert_eq!(*dropped_fields.borrow(), &[1, 2]);
+
+    // The same holds for tuple structs
+    let dropped_fields = Rc::new(RefCell::new(Vec::new()));
+    let cloned = AssertUnwindSafe(dropped_fields.clone());
+    panic::catch_unwind(|| {
+        TestTupleStruct(PushOnDrop::new(2, cloned.clone()),
+                        PushOnDrop::new(1, cloned.clone()),
+                        panic!("this panic is caught :D"));
+    }).err().unwrap();
+    assert_eq!(*dropped_fields.borrow(), &[1, 2]);
+}
+
+fn test_drop_enum() {
+    // Enum variants are dropped in the same order they are declared
+    let dropped_fields = Rc::new(RefCell::new(Vec::new()));
+    let test_struct_enum = TestEnum::Struct {
+        x: PushOnDrop::new(1, dropped_fields.clone()),
+        y: PushOnDrop::new(2, dropped_fields.clone()),
+        z: PushOnDrop::new(3, dropped_fields.clone())
+    };
+    drop(test_struct_enum);
+    assert_eq!(*dropped_fields.borrow(), &[1, 2, 3]);
+
+    // The same holds for tuple enum variants
+    let dropped_fields = Rc::new(RefCell::new(Vec::new()));
+    let test_tuple_enum = TestEnum::Tuple(PushOnDrop::new(1, dropped_fields.clone()),
+                                          PushOnDrop::new(2, dropped_fields.clone()),
+                                          PushOnDrop::new(3, dropped_fields.clone()));
+    drop(test_tuple_enum);
+    assert_eq!(*dropped_fields.borrow(), &[1, 2, 3]);
+
+    // Panic during enum construction means that fields are treated as local variables
+    // Therefore they are dropped in reverse order of initialization
+    let dropped_fields = Rc::new(RefCell::new(Vec::new()));
+    let cloned = AssertUnwindSafe(dropped_fields.clone());
+    panic::catch_unwind(|| {
+        TestEnum::Struct {
+            x: PushOnDrop::new(2, cloned.clone()),
+            y: PushOnDrop::new(1, cloned.clone()),
+            z: panic!("this panic is caught :D")
+        };
+    }).err().unwrap();
+    assert_eq!(*dropped_fields.borrow(), &[1, 2]);
+
+    // Test with different initialization order
+    let dropped_fields = Rc::new(RefCell::new(Vec::new()));
+    let cloned = AssertUnwindSafe(dropped_fields.clone());
+    panic::catch_unwind(|| {
+        TestEnum::Struct {
+            y: PushOnDrop::new(2, cloned.clone()),
+            x: PushOnDrop::new(1, cloned.clone()),
+            z: panic!("this panic is caught :D")
+        };
+    }).err().unwrap();
+    assert_eq!(*dropped_fields.borrow(), &[1, 2]);
+
+    // The same holds for tuple enum variants
+    let dropped_fields = Rc::new(RefCell::new(Vec::new()));
+    let cloned = AssertUnwindSafe(dropped_fields.clone());
+    panic::catch_unwind(|| {
+        TestEnum::Tuple(PushOnDrop::new(2, cloned.clone()),
+                        PushOnDrop::new(1, cloned.clone()),
+                        panic!("this panic is caught :D"));
+    }).err().unwrap();
+    assert_eq!(*dropped_fields.borrow(), &[1, 2]);
+}
+
+fn test_drop_list() {
+    // Elements in a Vec are dropped in the same order they are pushed
+    let dropped_fields = Rc::new(RefCell::new(Vec::new()));
+    let xs = vec![PushOnDrop::new(1, dropped_fields.clone()),
+                  PushOnDrop::new(2, dropped_fields.clone()),
+                  PushOnDrop::new(3, dropped_fields.clone())];
+    drop(xs);
+    assert_eq!(*dropped_fields.borrow(), &[1, 2, 3]);
+
+    // The same holds for arrays
+    let dropped_fields = Rc::new(RefCell::new(Vec::new()));
+    let xs = [PushOnDrop::new(1, dropped_fields.clone()),
+              PushOnDrop::new(2, dropped_fields.clone()),
+              PushOnDrop::new(3, dropped_fields.clone())];
+    drop(xs);
+    assert_eq!(*dropped_fields.borrow(), &[1, 2, 3]);
+
+    // Panic during vec construction means that fields are treated as local variables
+    // Therefore they are dropped in reverse order of initialization
+    let dropped_fields = Rc::new(RefCell::new(Vec::new()));
+    let cloned = AssertUnwindSafe(dropped_fields.clone());
+    panic::catch_unwind(|| {
+        vec![
+            PushOnDrop::new(2, cloned.clone()),
+            PushOnDrop::new(1, cloned.clone()),
+            panic!("this panic is caught :D")
+        ];
+    }).err().unwrap();
+    assert_eq!(*dropped_fields.borrow(), &[1, 2]);
+
+    // The same holds for arrays
+    let dropped_fields = Rc::new(RefCell::new(Vec::new()));
+    let cloned = AssertUnwindSafe(dropped_fields.clone());
+    panic::catch_unwind(|| {
+        [
+            PushOnDrop::new(2, cloned.clone()),
+            PushOnDrop::new(1, cloned.clone()),
+            panic!("this panic is caught :D")
+        ];
+    }).err().unwrap();
+    assert_eq!(*dropped_fields.borrow(), &[1, 2]);
+}
+
+fn main() {
+    test_drop_tuple();
+    test_drop_struct();
+    test_drop_enum();
+    test_drop_list();
+}