summary refs log tree commit diff
path: root/src/test/ui/rfcs
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-07-27 01:33:01 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-07-27 18:56:16 +0300
commit9be35f82c1abf2ecbab489bca9eca138ea648312 (patch)
tree69888506e34af447d9748c0d542de3ba1dd76210 /src/test/ui/rfcs
parentca9faa52f5ada0054b1fa27d97aedf448afb059b (diff)
downloadrust-9be35f82c1abf2ecbab489bca9eca138ea648312.tar.gz
rust-9be35f82c1abf2ecbab489bca9eca138ea648312.zip
tests: Move run-pass tests without naming conflicts to ui
Diffstat (limited to 'src/test/ui/rfcs')
-rw-r--r--src/test/ui/rfcs/rfc-1014-2.rs30
-rw-r--r--src/test/ui/rfcs/rfc-1014.rs34
-rw-r--r--src/test/ui/rfcs/rfc-1789-as-cell/from-mut.rs11
-rw-r--r--src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs6
-rw-r--r--src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs2
-rw-r--r--src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs8
-rw-r--r--src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs4
-rw-r--r--src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs6
-rw-r--r--src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs6
-rw-r--r--src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs4
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/box.rs18
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/constref.rs40
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/enum.rs45
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/for.rs20
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/general.rs249
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/lit.rs34
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/range.rs9
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/ref-region.rs16
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/reset-mode.rs14
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs26
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/struct.rs22
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs19
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple.rs12
-rw-r--r--src/test/ui/rfcs/rfc-2151-raw-identifiers/attr.rs15
-rw-r--r--src/test/ui/rfcs/rfc-2151-raw-identifiers/basic.rs20
-rw-r--r--src/test/ui/rfcs/rfc-2151-raw-identifiers/items.rs32
-rw-r--r--src/test/ui/rfcs/rfc-2151-raw-identifiers/macros.rs38
-rw-r--r--src/test/ui/rfcs/rfc-2175-or-if-while-let/basic.rs33
-rw-r--r--src/test/ui/rfcs/rfc-2302-self-struct-ctor.rs127
-rw-r--r--src/test/ui/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs15
-rw-r--r--src/test/ui/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs23
-rw-r--r--src/test/ui/rfcs/rfc1445/eq-allows-match.rs17
-rw-r--r--src/test/ui/rfcs/rfc1623.rs75
-rw-r--r--src/test/ui/rfcs/rfc1717/auxiliary/clibrary.rs5
-rw-r--r--src/test/ui/rfcs/rfc1717/library-override.rs14
-rw-r--r--src/test/ui/rfcs/rfc1857-drop-order.rs224
36 files changed, 1273 insertions, 0 deletions
diff --git a/src/test/ui/rfcs/rfc-1014-2.rs b/src/test/ui/rfcs/rfc-1014-2.rs
new file mode 100644
index 00000000000..5be092204d7
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-1014-2.rs
@@ -0,0 +1,30 @@
+// 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 world");
+}
+
+#[cfg(not(windows))]
+fn main() {}
diff --git a/src/test/ui/rfcs/rfc-1014.rs b/src/test/ui/rfcs/rfc-1014.rs
new file mode 100644
index 00000000000..41a036958bf
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-1014.rs
@@ -0,0 +1,34 @@
+// run-pass
+#![allow(dead_code)]
+// ignore-cloudabi stdout does not map to file descriptor 1 by default
+// 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 world");
+}
diff --git a/src/test/ui/rfcs/rfc-1789-as-cell/from-mut.rs b/src/test/ui/rfcs/rfc-1789-as-cell/from-mut.rs
new file mode 100644
index 00000000000..ea3ad7aed49
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-1789-as-cell/from-mut.rs
@@ -0,0 +1,11 @@
+// run-pass
+
+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);
+}
diff --git a/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs
new file mode 100644
index 00000000000..e98582cbce3
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs
new file mode 100644
index 00000000000..bac695d4e79
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs
@@ -0,0 +1,2 @@
+// run-pass
+fn main() {}
diff --git a/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs
new file mode 100644
index 00000000000..9c2270bf827
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs
@@ -0,0 +1,8 @@
+// run-pass
+#![feature(process_exitcode_placeholder)]
+
+use std::process::ExitCode;
+
+fn main() -> ExitCode {
+    ExitCode::SUCCESS
+}
diff --git a/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs
new file mode 100644
index 00000000000..79cfba011c0
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs
@@ -0,0 +1,4 @@
+// run-pass
+#![feature(termination_trait_lib)]
+
+fn main() -> impl std::process::Termination { }
diff --git a/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs
new file mode 100644
index 00000000000..b0e932e1fe0
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs
new file mode 100644
index 00000000000..30f36c24489
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs b/src/test/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs
new file mode 100644
index 00000000000..f0591c38c00
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc-2005-default-binding-mode/box.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/box.rs
new file mode 100644
index 00000000000..b3be41599a5
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/box.rs
@@ -0,0 +1,18 @@
+// run-pass
+#![allow(unreachable_patterns)]
+#![feature(box_syntax, box_patterns)]
+
+struct Foo{}
+
+pub fn main() {
+    let b = box Foo{};
+    let box f = &b;
+    let _: &Foo = f;
+
+    match &&&b {
+        box f => {
+            let _: &Foo = f;
+        },
+        _ => panic!(),
+    }
+}
diff --git a/src/test/ui/rfcs/rfc-2005-default-binding-mode/constref.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/constref.rs
new file mode 100644
index 00000000000..d5bca6a2474
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc-2005-default-binding-mode/enum.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/enum.rs
new file mode 100644
index 00000000000..52fbb90ed54
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc-2005-default-binding-mode/for.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/for.rs
new file mode 100644
index 00000000000..a5a24a80634
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc-2005-default-binding-mode/general.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/general.rs
new file mode 100644
index 00000000000..0207f607be8
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc-2005-default-binding-mode/lit.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/lit.rs
new file mode 100644
index 00000000000..9379753598e
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc-2005-default-binding-mode/range.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/range.rs
new file mode 100644
index 00000000000..580e67513b3
--- /dev/null
+++ b/src/test/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!(),
+        3 ..= 8 => {},
+        _ => panic!(),
+    }
+}
diff --git a/src/test/ui/rfcs/rfc-2005-default-binding-mode/ref-region.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/ref-region.rs
new file mode 100644
index 00000000000..b74e45c9328
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc-2005-default-binding-mode/reset-mode.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/reset-mode.rs
new file mode 100644
index 00000000000..3b9d07610d2
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs
new file mode 100644
index 00000000000..939a3c4a1fd
--- /dev/null
+++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs
@@ -0,0 +1,26 @@
+// run-pass
+#![feature(slice_patterns)]
+
+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/src/test/ui/rfcs/rfc-2005-default-binding-mode/struct.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/struct.rs
new file mode 100644
index 00000000000..5a00e5b6823
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs
new file mode 100644
index 00000000000..0cf9ba1b4ca
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/tuple.rs
new file mode 100644
index 00000000000..4c22aa2d718
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc-2151-raw-identifiers/attr.rs b/src/test/ui/rfcs/rfc-2151-raw-identifiers/attr.rs
new file mode 100644
index 00000000000..2fe1e05e509
--- /dev/null
+++ b/src/test/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(u32);
+
+pub fn main() {
+    assert_eq!(mem::size_of::<Test>(), 9);
+    assert_eq!("Test2(123)", format!("{:?}", Test2(123)));
+}
diff --git a/src/test/ui/rfcs/rfc-2151-raw-identifiers/basic.rs b/src/test/ui/rfcs/rfc-2151-raw-identifiers/basic.rs
new file mode 100644
index 00000000000..f2fe59668da
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc-2151-raw-identifiers/items.rs b/src/test/ui/rfcs/rfc-2151-raw-identifiers/items.rs
new file mode 100644
index 00000000000..4665225178c
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc-2151-raw-identifiers/macros.rs b/src/test/ui/rfcs/rfc-2151-raw-identifiers/macros.rs
new file mode 100644
index 00000000000..0ab7e17f87b
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc-2175-or-if-while-let/basic.rs b/src/test/ui/rfcs/rfc-2175-or-if-while-let/basic.rs
new file mode 100644
index 00000000000..22f04c58f3b
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc-2302-self-struct-ctor.rs b/src/test/ui/rfcs/rfc-2302-self-struct-ctor.rs
new file mode 100644
index 00000000000..1ec20c50034
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs b/src/test/ui/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs
new file mode 100644
index 00000000000..6d7bca4da24
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs b/src/test/ui/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs
new file mode 100644
index 00000000000..17174e22c74
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc1445/eq-allows-match.rs b/src/test/ui/rfcs/rfc1445/eq-allows-match.rs
new file mode 100644
index 00000000000..405a69c94bf
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc1623.rs b/src/test/ui/rfcs/rfc1623.rs
new file mode 100644
index 00000000000..adaf25c6bbf
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc1717/auxiliary/clibrary.rs b/src/test/ui/rfcs/rfc1717/auxiliary/clibrary.rs
new file mode 100644
index 00000000000..c1c5b70bc04
--- /dev/null
+++ b/src/test/ui/rfcs/rfc1717/auxiliary/clibrary.rs
@@ -0,0 +1,5 @@
+// no-prefer-dynamic
+#![crate_type = "staticlib"]
+
+#[no_mangle]
+pub extern "C" fn foo(x:i32) -> i32 { x }
diff --git a/src/test/ui/rfcs/rfc1717/library-override.rs b/src/test/ui/rfcs/rfc1717/library-override.rs
new file mode 100644
index 00000000000..014ccac31b7
--- /dev/null
+++ b/src/test/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/src/test/ui/rfcs/rfc1857-drop-order.rs b/src/test/ui/rfcs/rfc1857-drop-order.rs
new file mode 100644
index 00000000000..7923aa7c0e2
--- /dev/null
+++ b/src/test/ui/rfcs/rfc1857-drop-order.rs
@@ -0,0 +1,224 @@
+// run-pass
+// ignore-wasm32-bare compiled with panic=abort by default
+
+#![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();
+}