]> git.lizzy.rs Git - rust.git/commitdiff
Organize `never_type` tests
authorMazdak Farrokhzad <twingoow@gmail.com>
Tue, 15 Oct 2019 13:28:42 +0000 (15:28 +0200)
committerMazdak Farrokhzad <twingoow@gmail.com>
Tue, 15 Oct 2019 14:58:14 +0000 (16:58 +0200)
Also move {run-fail -> ui}/never_type

98 files changed:
src/test/run-fail/adjust_never.rs [deleted file]
src/test/run-fail/call-fn-never-arg.rs [deleted file]
src/test/run-fail/cast-never.rs [deleted file]
src/test/run-fail/never-associated-type.rs [deleted file]
src/test/run-fail/never-type-arg.rs [deleted file]
src/test/ui/always-inhabited-union-ref.rs [deleted file]
src/test/ui/always-inhabited-union-ref.stderr [deleted file]
src/test/ui/call-fn-never-arg-wrong-type.rs [deleted file]
src/test/ui/call-fn-never-arg-wrong-type.stderr [deleted file]
src/test/ui/coercion/coerce-issue-49593-box-never.rs
src/test/ui/defaulted-never-note.rs [deleted file]
src/test/ui/defaulted-never-note.stderr [deleted file]
src/test/ui/dispatch_from_dyn_zst.rs [deleted file]
src/test/ui/diverging-fallback-control-flow.rs [deleted file]
src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs
src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr
src/test/ui/for-loop-while/loop-break-value.rs
src/test/ui/impl-for-never.rs [deleted file]
src/test/ui/issues/issue-13352.rs [deleted file]
src/test/ui/issues/issue-13352.stderr [deleted file]
src/test/ui/issues/issue-2149.rs [deleted file]
src/test/ui/issues/issue-2149.stderr [deleted file]
src/test/ui/issues/issue-44402.rs [deleted file]
src/test/ui/lint/must_use-unit.rs
src/test/ui/lint/must_use-unit.stderr
src/test/ui/never-assign-dead-code.rs [deleted file]
src/test/ui/never-assign-dead-code.stderr [deleted file]
src/test/ui/never-assign-wrong-type.rs [deleted file]
src/test/ui/never-assign-wrong-type.stderr [deleted file]
src/test/ui/never-from-impl-is-reserved.rs [deleted file]
src/test/ui/never-from-impl-is-reserved.stderr [deleted file]
src/test/ui/never-result.rs [deleted file]
src/test/ui/never-type-rvalues.rs [deleted file]
src/test/ui/never_coercions.rs [deleted file]
src/test/ui/never_transmute_never.rs [deleted file]
src/test/ui/never_type/adjust_never.rs [new file with mode: 0644]
src/test/ui/never_type/call-fn-never-arg-wrong-type.rs [new file with mode: 0644]
src/test/ui/never_type/call-fn-never-arg-wrong-type.stderr [new file with mode: 0644]
src/test/ui/never_type/call-fn-never-arg.rs [new file with mode: 0644]
src/test/ui/never_type/cast-never.rs [new file with mode: 0644]
src/test/ui/never_type/defaulted-never-note.rs [new file with mode: 0644]
src/test/ui/never_type/defaulted-never-note.stderr [new file with mode: 0644]
src/test/ui/never_type/dispatch_from_dyn_zst.rs [new file with mode: 0644]
src/test/ui/never_type/diverging-fallback-control-flow.rs [new file with mode: 0644]
src/test/ui/never_type/impl-for-never.rs [new file with mode: 0644]
src/test/ui/never_type/issue-13352.rs [new file with mode: 0644]
src/test/ui/never_type/issue-13352.stderr [new file with mode: 0644]
src/test/ui/never_type/issue-2149.rs [new file with mode: 0644]
src/test/ui/never_type/issue-2149.stderr [new file with mode: 0644]
src/test/ui/never_type/issue-44402.rs [new file with mode: 0644]
src/test/ui/never_type/never-assign-dead-code.rs [new file with mode: 0644]
src/test/ui/never_type/never-assign-dead-code.stderr [new file with mode: 0644]
src/test/ui/never_type/never-assign-wrong-type.rs [new file with mode: 0644]
src/test/ui/never_type/never-assign-wrong-type.stderr [new file with mode: 0644]
src/test/ui/never_type/never-associated-type.rs [new file with mode: 0644]
src/test/ui/never_type/never-from-impl-is-reserved.rs [new file with mode: 0644]
src/test/ui/never_type/never-from-impl-is-reserved.stderr [new file with mode: 0644]
src/test/ui/never_type/never-result.rs [new file with mode: 0644]
src/test/ui/never_type/never-type-arg.rs [new file with mode: 0644]
src/test/ui/never_type/never-type-rvalues.rs [new file with mode: 0644]
src/test/ui/never_type/never_coercions.rs [new file with mode: 0644]
src/test/ui/never_type/never_transmute_never.rs [new file with mode: 0644]
src/test/ui/never_type/panic-uninitialized-zeroed.rs [new file with mode: 0644]
src/test/ui/never_type/try_from.rs [new file with mode: 0644]
src/test/ui/panic-uninitialized-zeroed.rs [deleted file]
src/test/ui/reachable/auxiliary/unreachable_variant.rs [new file with mode: 0644]
src/test/ui/reachable/unreachable-arm.rs [new file with mode: 0644]
src/test/ui/reachable/unreachable-arm.stderr [new file with mode: 0644]
src/test/ui/reachable/unreachable-code.rs [new file with mode: 0644]
src/test/ui/reachable/unreachable-code.stderr [new file with mode: 0644]
src/test/ui/reachable/unreachable-in-call.rs [new file with mode: 0644]
src/test/ui/reachable/unreachable-in-call.stderr [new file with mode: 0644]
src/test/ui/reachable/unreachable-loop-patterns.rs [new file with mode: 0644]
src/test/ui/reachable/unreachable-loop-patterns.stderr [new file with mode: 0644]
src/test/ui/reachable/unreachable-try-pattern.rs [new file with mode: 0644]
src/test/ui/reachable/unreachable-try-pattern.stderr [new file with mode: 0644]
src/test/ui/reachable/unreachable-variant.rs [new file with mode: 0644]
src/test/ui/reachable/unreachable-variant.stderr [new file with mode: 0644]
src/test/ui/reachable/unwarned-match-on-never.rs [new file with mode: 0644]
src/test/ui/reachable/unwarned-match-on-never.stderr [new file with mode: 0644]
src/test/ui/try_from.rs [deleted file]
src/test/ui/uninhabited/always-inhabited-union-ref.rs [new file with mode: 0644]
src/test/ui/uninhabited/always-inhabited-union-ref.stderr [new file with mode: 0644]
src/test/ui/unreachable/auxiliary/unreachable_variant.rs [deleted file]
src/test/ui/unreachable/unreachable-arm.rs [deleted file]
src/test/ui/unreachable/unreachable-arm.stderr [deleted file]
src/test/ui/unreachable/unreachable-code.rs [deleted file]
src/test/ui/unreachable/unreachable-code.stderr [deleted file]
src/test/ui/unreachable/unreachable-in-call.rs [deleted file]
src/test/ui/unreachable/unreachable-in-call.stderr [deleted file]
src/test/ui/unreachable/unreachable-loop-patterns.rs [deleted file]
src/test/ui/unreachable/unreachable-loop-patterns.stderr [deleted file]
src/test/ui/unreachable/unreachable-try-pattern.rs [deleted file]
src/test/ui/unreachable/unreachable-try-pattern.stderr [deleted file]
src/test/ui/unreachable/unreachable-variant.rs [deleted file]
src/test/ui/unreachable/unreachable-variant.stderr [deleted file]
src/test/ui/unreachable/unwarned-match-on-never.rs [deleted file]
src/test/ui/unreachable/unwarned-match-on-never.stderr [deleted file]

diff --git a/src/test/run-fail/adjust_never.rs b/src/test/run-fail/adjust_never.rs
deleted file mode 100644 (file)
index 8661a2f..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// Test that a variable of type ! can coerce to another type.
-
-// error-pattern:explicit
-
-#![feature(never_type)]
-
-fn main() {
-    let x: ! = panic!();
-    let y: u32 = x;
-}
diff --git a/src/test/run-fail/call-fn-never-arg.rs b/src/test/run-fail/call-fn-never-arg.rs
deleted file mode 100644 (file)
index f5b2cfa..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// Test that we can use a ! for an argument of type !
-
-// error-pattern:wowzers!
-
-#![feature(never_type)]
-#![allow(unreachable_code)]
-
-fn foo(x: !) -> ! {
-    x
-}
-
-fn main() {
-    foo(panic!("wowzers!"))
-}
diff --git a/src/test/run-fail/cast-never.rs b/src/test/run-fail/cast-never.rs
deleted file mode 100644 (file)
index 0b05a4b..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// Test that we can explicitly cast ! to another type
-
-// error-pattern:explicit
-
-#![feature(never_type)]
-
-fn main() {
-    let x: ! = panic!();
-    let y: u32 = x as u32;
-}
diff --git a/src/test/run-fail/never-associated-type.rs b/src/test/run-fail/never-associated-type.rs
deleted file mode 100644 (file)
index 587f0f7..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// Test that we can use ! as an associated type.
-
-// error-pattern:kapow!
-
-#![feature(never_type)]
-
-trait Foo {
-    type Wow;
-
-    fn smeg(&self) -> Self::Wow;
-}
-
-struct Blah;
-impl Foo for Blah {
-    type Wow = !;
-    fn smeg(&self) -> ! {
-        panic!("kapow!");
-    }
-}
-
-fn main() {
-    Blah.smeg();
-}
diff --git a/src/test/run-fail/never-type-arg.rs b/src/test/run-fail/never-type-arg.rs
deleted file mode 100644 (file)
index 1747e96..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// Test that we can use ! as an argument to a trait impl.
-
-// error-pattern:oh no!
-
-#![feature(never_type)]
-
-struct Wub;
-
-impl PartialEq<!> for Wub {
-    fn eq(&self, other: &!) -> bool {
-        *other
-    }
-}
-
-fn main() {
-    let _ = Wub == panic!("oh no!");
-}
diff --git a/src/test/ui/always-inhabited-union-ref.rs b/src/test/ui/always-inhabited-union-ref.rs
deleted file mode 100644 (file)
index 11eae2a..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-// The precise semantics of inhabitedness with respect to unions and references is currently
-// undecided. This test file currently checks a conservative choice.
-
-#![feature(exhaustive_patterns)]
-#![feature(never_type)]
-
-#![allow(dead_code)]
-#![allow(unreachable_code)]
-
-pub union Foo {
-    foo: !,
-}
-
-fn uninhab_ref() -> &'static ! {
-    unimplemented!()
-}
-
-fn uninhab_union() -> Foo {
-    unimplemented!()
-}
-
-fn match_on_uninhab() {
-    match uninhab_ref() {
-        //~^ ERROR non-exhaustive patterns: type `&'static !` is non-empty
-    }
-
-    match uninhab_union() {
-        //~^ ERROR non-exhaustive patterns: type `Foo` is non-empty
-    }
-}
-
-fn main() {}
diff --git a/src/test/ui/always-inhabited-union-ref.stderr b/src/test/ui/always-inhabited-union-ref.stderr
deleted file mode 100644 (file)
index 792ab6f..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-error[E0004]: non-exhaustive patterns: type `&'static !` is non-empty
-  --> $DIR/always-inhabited-union-ref.rs:23:11
-   |
-LL |     match uninhab_ref() {
-   |           ^^^^^^^^^^^^^
-   |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-
-error[E0004]: non-exhaustive patterns: type `Foo` is non-empty
-  --> $DIR/always-inhabited-union-ref.rs:27:11
-   |
-LL |     match uninhab_union() {
-   |           ^^^^^^^^^^^^^^^
-   |
-   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/call-fn-never-arg-wrong-type.rs b/src/test/ui/call-fn-never-arg-wrong-type.rs
deleted file mode 100644 (file)
index d06637e..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// Test that we can't pass other types for !
-
-#![feature(never_type)]
-
-fn foo(x: !) -> ! {
-    x
-}
-
-fn main() {
-    foo("wow"); //~ ERROR mismatched types
-}
diff --git a/src/test/ui/call-fn-never-arg-wrong-type.stderr b/src/test/ui/call-fn-never-arg-wrong-type.stderr
deleted file mode 100644 (file)
index 7a50fd3..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/call-fn-never-arg-wrong-type.rs:10:9
-   |
-LL |     foo("wow");
-   |         ^^^^^ expected !, found reference
-   |
-   = note: expected type `!`
-              found type `&'static str`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0308`.
index f005245e6dcb9141f6d0d4228159ccef678e5e62..5038eb3ebf4583db98b83239ee4860f7a1a66581 100644 (file)
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![feature(never_type)]
 #![allow(unreachable_code)]
diff --git a/src/test/ui/defaulted-never-note.rs b/src/test/ui/defaulted-never-note.rs
deleted file mode 100644 (file)
index d3fb8a0..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-// We need to opt into the `!` feature in order to trigger the
-// requirement that this is testing.
-#![feature(never_type)]
-
-#![allow(unused)]
-
-trait Deserialize: Sized {
-    fn deserialize() -> Result<Self, String>;
-}
-
-impl Deserialize for () {
-    fn deserialize() -> Result<(), String> {
-        Ok(())
-    }
-}
-
-trait ImplementedForUnitButNotNever {}
-
-impl ImplementedForUnitButNotNever for () {}
-
-fn foo<T: ImplementedForUnitButNotNever>(_t: T) {}
-//~^ NOTE required by this bound in `foo`
-//~| NOTE
-
-fn smeg() {
-    let _x = return;
-    foo(_x);
-    //~^ ERROR the trait bound
-    //~| NOTE the trait `ImplementedForUnitButNotNever` is not implemented
-    //~| NOTE the trait is implemented for `()`
-}
-
-fn main() {
-    smeg();
-}
diff --git a/src/test/ui/defaulted-never-note.stderr b/src/test/ui/defaulted-never-note.stderr
deleted file mode 100644 (file)
index 28c9da0..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0277]: the trait bound `!: ImplementedForUnitButNotNever` is not satisfied
-  --> $DIR/defaulted-never-note.rs:27:5
-   |
-LL | fn foo<T: ImplementedForUnitButNotNever>(_t: T) {}
-   |    ---    ----------------------------- required by this bound in `foo`
-...
-LL |     foo(_x);
-   |     ^^^ the trait `ImplementedForUnitButNotNever` is not implemented for `!`
-   |
-   = note: the trait is implemented for `()`. Possibly this error has been caused by changes to Rust's type-inference algorithm (see: https://github.com/rust-lang/rust/issues/48950 for more info). Consider whether you meant to use the type `()` here instead.
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/dispatch_from_dyn_zst.rs b/src/test/ui/dispatch_from_dyn_zst.rs
deleted file mode 100644 (file)
index 764f58c..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-// run-pass
-
-#![feature(unsize, dispatch_from_dyn, never_type)]
-
-#![allow(dead_code)]
-
-use std::{
-    ops::DispatchFromDyn,
-    marker::{Unsize, PhantomData},
-};
-
-struct Zst;
-struct NestedZst(PhantomData<()>, Zst);
-
-
-struct WithUnit<T: ?Sized>(Box<T>, ());
-impl<T: ?Sized, U: ?Sized> DispatchFromDyn<WithUnit<U>> for WithUnit<T>
-    where T: Unsize<U> {}
-
-struct WithPhantom<T: ?Sized>(Box<T>, PhantomData<()>);
-impl<T: ?Sized, U: ?Sized> DispatchFromDyn<WithPhantom<U>> for WithPhantom<T>
-    where T: Unsize<U> {}
-
-struct WithNever<T: ?Sized>(Box<T>, !);
-impl<T: ?Sized, U: ?Sized> DispatchFromDyn<WithNever<U>> for WithNever<T>
-    where T: Unsize<U> {}
-
-struct WithZst<T: ?Sized>(Box<T>, Zst);
-impl<T: ?Sized, U: ?Sized> DispatchFromDyn<WithZst<U>> for WithZst<T>
-    where T: Unsize<U> {}
-
-struct WithNestedZst<T: ?Sized>(Box<T>, NestedZst);
-impl<T: ?Sized, U: ?Sized> DispatchFromDyn<WithNestedZst<U>> for WithNestedZst<T>
-    where T: Unsize<U> {}
-
-
-struct Generic<T: ?Sized, A>(Box<T>, A);
-impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Generic<U, ()>> for Generic<T, ()>
-    where T: Unsize<U> {}
-impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Generic<U, PhantomData<()>>>
-    for Generic<T, PhantomData<()>>
-    where T: Unsize<U> {}
-impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Generic<U, !>> for Generic<T, !>
-    where T: Unsize<U> {}
-impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Generic<U, Zst>> for Generic<T, Zst>
-    where T: Unsize<U> {}
-impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Generic<U, NestedZst>> for Generic<T, NestedZst>
-    where T: Unsize<U> {}
-
-
-fn main() {}
diff --git a/src/test/ui/diverging-fallback-control-flow.rs b/src/test/ui/diverging-fallback-control-flow.rs
deleted file mode 100644 (file)
index 0f0f787..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-// run-pass
-
-#![allow(dead_code)]
-#![allow(unused_assignments)]
-#![allow(unused_variables)]
-#![allow(unreachable_code)]
-// Test various cases where we permit an unconstrained variable
-// to fallback based on control-flow.
-//
-// These represent current behavior, but are pretty dubious.  I would
-// like to revisit these and potentially change them. --nmatsakis
-
-#![feature(never_type)]
-
-trait BadDefault {
-    fn default() -> Self;
-}
-
-impl BadDefault for u32 {
-    fn default() -> Self {
-        0
-    }
-}
-
-impl BadDefault for ! {
-    fn default() -> ! {
-        panic!()
-    }
-}
-
-fn assignment() {
-    let x;
-
-    if true {
-        x = BadDefault::default();
-    } else {
-        x = return;
-    }
-}
-
-fn assignment_rev() {
-    let x;
-
-    if true {
-        x = return;
-    } else {
-        x = BadDefault::default();
-    }
-}
-
-fn if_then_else() {
-    let _x = if true {
-        BadDefault::default()
-    } else {
-        return;
-    };
-}
-
-fn if_then_else_rev() {
-    let _x = if true {
-        return;
-    } else {
-        BadDefault::default()
-    };
-}
-
-fn match_arm() {
-    let _x = match Ok(BadDefault::default()) {
-        Ok(v) => v,
-        Err(()) => return,
-    };
-}
-
-fn match_arm_rev() {
-    let _x = match Ok(BadDefault::default()) {
-        Err(()) => return,
-        Ok(v) => v,
-    };
-}
-
-fn loop_break() {
-    let _x = loop {
-        if false {
-            break return;
-        } else {
-            break BadDefault::default();
-        }
-    };
-}
-
-fn loop_break_rev() {
-    let _x = loop {
-        if false {
-            break return;
-        } else {
-            break BadDefault::default();
-        }
-    };
-}
-
-fn main() { }
index 27ff5ace25ddc2754e312b7de0c71a80e51c7b86..f0cc9ea70550e6a7cf8483d35a0869a48ff4282b 100644 (file)
@@ -1,4 +1,5 @@
 #![feature(never_type)]
+
 fn foo() -> Result<u32, !> {
     Ok(123)
 }
index d77fbc1e8239debff1410553b2f698755bc305b8..08c36cece4cf9b42ebed048ddf39aaacc3e1c856 100644 (file)
@@ -1,5 +1,5 @@
 error[E0005]: refutable pattern in local binding: `Err(_)` not covered
-  --> $DIR/feature-gate-exhaustive-patterns.rs:7:9
+  --> $DIR/feature-gate-exhaustive-patterns.rs:8:9
    |
 LL |     let Ok(_x) = foo();
    |         ^^^^^^ pattern `Err(_)` not covered
index e1edbbb929e6a4236f99a1e8bc81711161379d0a..d7209fc4de867f168c5db50c403efc4ba33abf49 100644 (file)
@@ -1,4 +1,5 @@
 // run-pass
+
 #![allow(unreachable_code)]
 #![feature(never_type)]
 
diff --git a/src/test/ui/impl-for-never.rs b/src/test/ui/impl-for-never.rs
deleted file mode 100644 (file)
index c5f1298..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// run-pass
-// Test that we can call static methods on ! both directly and when it appears in a generic
-
-#![feature(never_type)]
-
-trait StringifyType {
-    fn stringify_type() -> &'static str;
-}
-
-impl StringifyType for ! {
-    fn stringify_type() -> &'static str {
-        "!"
-    }
-}
-
-fn maybe_stringify<T: StringifyType>(opt: Option<T>) -> &'static str {
-    match opt {
-        Some(_) => T::stringify_type(),
-        None => "none",
-    }
-}
-
-fn main() {
-    println!("! is {}", <!>::stringify_type());
-    println!("None is {}", maybe_stringify(None::<!>));
-}
diff --git a/src/test/ui/issues/issue-13352.rs b/src/test/ui/issues/issue-13352.rs
deleted file mode 100644 (file)
index e6995be..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// ignore-cloudabi no std::process
-
-fn foo(_: Box<dyn FnMut()>) {}
-
-fn main() {
-    foo(loop {
-        std::process::exit(0);
-    });
-    2_usize + (loop {});
-    //~^ ERROR E0277
-}
diff --git a/src/test/ui/issues/issue-13352.stderr b/src/test/ui/issues/issue-13352.stderr
deleted file mode 100644 (file)
index 58ac74b..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0277]: cannot add `()` to `usize`
-  --> $DIR/issue-13352.rs:9:13
-   |
-LL |     2_usize + (loop {});
-   |             ^ no implementation for `usize + ()`
-   |
-   = help: the trait `std::ops::Add<()>` is not implemented for `usize`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/issues/issue-2149.rs b/src/test/ui/issues/issue-2149.rs
deleted file mode 100644 (file)
index d46f0e6..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-trait VecMonad<A> {
-    fn bind<B, F>(&self, f: F) where F: FnMut(A) -> Vec<B>;
-}
-
-impl<A> VecMonad<A> for Vec<A> {
-    fn bind<B, F>(&self, mut f: F) where F: FnMut(A) -> Vec<B> {
-        let mut r = panic!();
-        for elt in self { r = r + f(*elt); }
-        //~^ ERROR E0277
-   }
-}
-fn main() {
-    ["hi"].bind(|x| [x] );
-    //~^ ERROR no method named `bind` found for type `[&str; 1]` in the current scope
-}
diff --git a/src/test/ui/issues/issue-2149.stderr b/src/test/ui/issues/issue-2149.stderr
deleted file mode 100644 (file)
index 8ce2ba0..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-error[E0277]: cannot add `std::vec::Vec<B>` to `()`
-  --> $DIR/issue-2149.rs:8:33
-   |
-LL |         for elt in self { r = r + f(*elt); }
-   |                                 ^ no implementation for `() + std::vec::Vec<B>`
-   |
-   = help: the trait `std::ops::Add<std::vec::Vec<B>>` is not implemented for `()`
-
-error[E0599]: no method named `bind` found for type `[&str; 1]` in the current scope
-  --> $DIR/issue-2149.rs:13:12
-   |
-LL |     ["hi"].bind(|x| [x] );
-   |            ^^^^ method not found in `[&str; 1]`
-   |
-   = help: items from traits can only be used if the trait is implemented and in scope
-   = note: the following trait defines an item `bind`, perhaps you need to implement it:
-           candidate #1: `VecMonad`
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0277, E0599.
-For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/issues/issue-44402.rs b/src/test/ui/issues/issue-44402.rs
deleted file mode 100644 (file)
index 29b7eb5..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-// build-pass (FIXME(62277): could be check-pass?)
-#![allow(dead_code)]
-#![feature(never_type)]
-#![feature(exhaustive_patterns)]
-
-// Regression test for inhabitedness check. The old
-// cache used to cause us to incorrectly decide
-// that `test_b` was invalid.
-
-struct Foo {
-    field1: !,
-    field2: Option<&'static Bar>,
-}
-
-struct Bar {
-    field1: &'static Foo
-}
-
-fn test_a() {
-    let x: Option<Foo> = None;
-    match x { None => () }
-}
-
-fn test_b() {
-    let x: Option<Bar> = None;
-    match x {
-        Some(_) => (),
-        None => ()
-    }
-}
-
-fn main() { }
index 92568252164f683d0b7e57ee78c564143553dffd..4dd4798abb7ce890e9cca2a72188bf028fb9d6ef 100644 (file)
@@ -1,5 +1,4 @@
 #![feature(never_type)]
-
 #![deny(unused_must_use)]
 
 #[must_use]
index f6229c0442f999f5157432e0acee4867f47fe708..0a9939b2015b7f14cc859b7c88238c27bc2745a7 100644 (file)
@@ -1,17 +1,17 @@
 error: unused return value of `foo` that must be used
-  --> $DIR/must_use-unit.rs:14:5
+  --> $DIR/must_use-unit.rs:13:5
    |
 LL |     foo();
    |     ^^^^^^
    |
 note: lint level defined here
-  --> $DIR/must_use-unit.rs:3:9
+  --> $DIR/must_use-unit.rs:2:9
    |
 LL | #![deny(unused_must_use)]
    |         ^^^^^^^^^^^^^^^
 
 error: unused return value of `bar` that must be used
-  --> $DIR/must_use-unit.rs:16:5
+  --> $DIR/must_use-unit.rs:15:5
    |
 LL |     bar();
    |     ^^^^^^
diff --git a/src/test/ui/never-assign-dead-code.rs b/src/test/ui/never-assign-dead-code.rs
deleted file mode 100644 (file)
index fd5fbc3..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// Test that an assignment of type ! makes the rest of the block dead code.
-
-#![feature(never_type)]
-// build-pass (FIXME(62277): could be check-pass?)
-#![warn(unused)]
-
-
-fn main() {
-    let x: ! = panic!("aah"); //~ WARN unused
-    drop(x); //~ WARN unreachable
-    //~^ WARN unreachable
-}
diff --git a/src/test/ui/never-assign-dead-code.stderr b/src/test/ui/never-assign-dead-code.stderr
deleted file mode 100644 (file)
index b887d58..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-warning: unreachable statement
-  --> $DIR/never-assign-dead-code.rs:10:5
-   |
-LL |     let x: ! = panic!("aah");
-   |                ------------- any code following this expression is unreachable
-LL |     drop(x);
-   |     ^^^^^^^^ unreachable statement
-   |
-note: lint level defined here
-  --> $DIR/never-assign-dead-code.rs:5:9
-   |
-LL | #![warn(unused)]
-   |         ^^^^^^
-   = note: `#[warn(unreachable_code)]` implied by `#[warn(unused)]`
-   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
-
-warning: unreachable call
-  --> $DIR/never-assign-dead-code.rs:10:5
-   |
-LL |     drop(x);
-   |     ^^^^ - any code following this expression is unreachable
-   |     |
-   |     unreachable call
-
-warning: unused variable: `x`
-  --> $DIR/never-assign-dead-code.rs:9:9
-   |
-LL |     let x: ! = panic!("aah");
-   |         ^ help: consider prefixing with an underscore: `_x`
-   |
-note: lint level defined here
-  --> $DIR/never-assign-dead-code.rs:5:9
-   |
-LL | #![warn(unused)]
-   |         ^^^^^^
-   = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
-
diff --git a/src/test/ui/never-assign-wrong-type.rs b/src/test/ui/never-assign-wrong-type.rs
deleted file mode 100644 (file)
index 67e26f5..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// Test that we can't use another type in place of !
-
-#![feature(never_type)]
-#![deny(warnings)]
-
-fn main() {
-    let x: ! = "hello"; //~ ERROR mismatched types
-}
diff --git a/src/test/ui/never-assign-wrong-type.stderr b/src/test/ui/never-assign-wrong-type.stderr
deleted file mode 100644 (file)
index da2e77d..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/never-assign-wrong-type.rs:7:16
-   |
-LL |     let x: ! = "hello";
-   |                ^^^^^^^ expected !, found reference
-   |
-   = note: expected type `!`
-              found type `&'static str`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/never-from-impl-is-reserved.rs b/src/test/ui/never-from-impl-is-reserved.rs
deleted file mode 100644 (file)
index 9d16015..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// check that the `for<T> T: From<!>` impl is reserved
-
-#![feature(never_type)]
-
-pub struct MyFoo;
-pub trait MyTrait {}
-
-impl MyTrait for MyFoo {}
-// This will conflict with the first impl if we impl `for<T> T: From<!>`.
-impl<T> MyTrait for T where T: From<!> {} //~ ERROR conflicting implementation
-
-fn main() {}
diff --git a/src/test/ui/never-from-impl-is-reserved.stderr b/src/test/ui/never-from-impl-is-reserved.stderr
deleted file mode 100644 (file)
index 8b8d0f4..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0119]: conflicting implementations of trait `MyTrait` for type `MyFoo`:
-  --> $DIR/never-from-impl-is-reserved.rs:10:1
-   |
-LL | impl MyTrait for MyFoo {}
-   | ---------------------- first implementation here
-LL | // This will conflict with the first impl if we impl `for<T> T: From<!>`.
-LL | impl<T> MyTrait for T where T: From<!> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyFoo`
-   |
-   = note: permitting this impl would forbid us from adding `impl<T> From<!> for T` later; see rust-lang/rust#64715 for details
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/never-result.rs b/src/test/ui/never-result.rs
deleted file mode 100644 (file)
index 98ce326..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// run-pass
-
-#![allow(unused_variables)]
-#![allow(unreachable_code)]
-// Test that we can extract a ! through pattern matching then use it as several different types.
-
-#![feature(never_type)]
-
-fn main() {
-    let x: Result<u32, !> = Ok(123);
-    match x {
-        Ok(z) => (),
-        Err(y) => {
-            let q: u32 = y;
-            let w: i32 = y;
-            let e: String = y;
-            y
-        },
-    }
-}
diff --git a/src/test/ui/never-type-rvalues.rs b/src/test/ui/never-type-rvalues.rs
deleted file mode 100644 (file)
index 9ccc73d..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-// run-pass
-
-#![feature(never_type)]
-#![allow(dead_code)]
-#![allow(path_statements)]
-#![allow(unreachable_patterns)]
-
-fn never_direct(x: !) {
-    x;
-}
-
-fn never_ref_pat(ref x: !) {
-    *x;
-}
-
-fn never_ref(x: &!) {
-    let &y = x;
-    y;
-}
-
-fn never_pointer(x: *const !) {
-    unsafe {
-        *x;
-    }
-}
-
-fn never_slice(x: &[!]) {
-    x[0];
-}
-
-fn never_match(x: Result<(), !>) {
-    match x {
-        Ok(_) => {},
-        Err(_) => {},
-    }
-}
-
-pub fn main() { }
diff --git a/src/test/ui/never_coercions.rs b/src/test/ui/never_coercions.rs
deleted file mode 100644 (file)
index 105c386..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// run-pass
-// Test that having something of type ! doesn't screw up type-checking and that it coerces to the
-// LUB type of the other match arms.
-
-fn main() {
-    let v: Vec<u32> = Vec::new();
-    match 0u32 {
-        0 => &v,
-        1 => return,
-        _ => &v[..],
-    };
-}
diff --git a/src/test/ui/never_transmute_never.rs b/src/test/ui/never_transmute_never.rs
deleted file mode 100644 (file)
index 5bad756..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// build-pass (FIXME(62277): could be check-pass?)
-
-#![crate_type="lib"]
-
-#![feature(never_type)]
-#![allow(dead_code)]
-#![allow(unreachable_code)]
-#![allow(unused_variables)]
-
-struct Foo;
-
-pub fn f(x: !) -> ! {
-    x
-}
-
-pub fn ub() {
-    // This is completely undefined behaviour,
-    // but we still want to make sure it compiles.
-    let x: ! = unsafe {
-        std::mem::transmute::<Foo, !>(Foo)
-    };
-    f(x)
-}
diff --git a/src/test/ui/never_type/adjust_never.rs b/src/test/ui/never_type/adjust_never.rs
new file mode 100644 (file)
index 0000000..3aa5866
--- /dev/null
@@ -0,0 +1,11 @@
+// Test that a variable of type ! can coerce to another type.
+
+// run-fail
+// error-pattern:explicit
+
+#![feature(never_type)]
+
+fn main() {
+    let x: ! = panic!();
+    let y: u32 = x;
+}
diff --git a/src/test/ui/never_type/call-fn-never-arg-wrong-type.rs b/src/test/ui/never_type/call-fn-never-arg-wrong-type.rs
new file mode 100644 (file)
index 0000000..d06637e
--- /dev/null
@@ -0,0 +1,11 @@
+// Test that we can't pass other types for !
+
+#![feature(never_type)]
+
+fn foo(x: !) -> ! {
+    x
+}
+
+fn main() {
+    foo("wow"); //~ ERROR mismatched types
+}
diff --git a/src/test/ui/never_type/call-fn-never-arg-wrong-type.stderr b/src/test/ui/never_type/call-fn-never-arg-wrong-type.stderr
new file mode 100644 (file)
index 0000000..7a50fd3
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+  --> $DIR/call-fn-never-arg-wrong-type.rs:10:9
+   |
+LL |     foo("wow");
+   |         ^^^^^ expected !, found reference
+   |
+   = note: expected type `!`
+              found type `&'static str`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/never_type/call-fn-never-arg.rs b/src/test/ui/never_type/call-fn-never-arg.rs
new file mode 100644 (file)
index 0000000..6218572
--- /dev/null
@@ -0,0 +1,15 @@
+// Test that we can use a ! for an argument of type !
+
+// run-fail
+// error-pattern:wowzers!
+
+#![feature(never_type)]
+#![allow(unreachable_code)]
+
+fn foo(x: !) -> ! {
+    x
+}
+
+fn main() {
+    foo(panic!("wowzers!"))
+}
diff --git a/src/test/ui/never_type/cast-never.rs b/src/test/ui/never_type/cast-never.rs
new file mode 100644 (file)
index 0000000..46072e1
--- /dev/null
@@ -0,0 +1,11 @@
+// Test that we can explicitly cast ! to another type
+
+// run-fail
+// error-pattern:explicit
+
+#![feature(never_type)]
+
+fn main() {
+    let x: ! = panic!();
+    let y: u32 = x as u32;
+}
diff --git a/src/test/ui/never_type/defaulted-never-note.rs b/src/test/ui/never_type/defaulted-never-note.rs
new file mode 100644 (file)
index 0000000..d3fb8a0
--- /dev/null
@@ -0,0 +1,35 @@
+// We need to opt into the `!` feature in order to trigger the
+// requirement that this is testing.
+#![feature(never_type)]
+
+#![allow(unused)]
+
+trait Deserialize: Sized {
+    fn deserialize() -> Result<Self, String>;
+}
+
+impl Deserialize for () {
+    fn deserialize() -> Result<(), String> {
+        Ok(())
+    }
+}
+
+trait ImplementedForUnitButNotNever {}
+
+impl ImplementedForUnitButNotNever for () {}
+
+fn foo<T: ImplementedForUnitButNotNever>(_t: T) {}
+//~^ NOTE required by this bound in `foo`
+//~| NOTE
+
+fn smeg() {
+    let _x = return;
+    foo(_x);
+    //~^ ERROR the trait bound
+    //~| NOTE the trait `ImplementedForUnitButNotNever` is not implemented
+    //~| NOTE the trait is implemented for `()`
+}
+
+fn main() {
+    smeg();
+}
diff --git a/src/test/ui/never_type/defaulted-never-note.stderr b/src/test/ui/never_type/defaulted-never-note.stderr
new file mode 100644 (file)
index 0000000..28c9da0
--- /dev/null
@@ -0,0 +1,14 @@
+error[E0277]: the trait bound `!: ImplementedForUnitButNotNever` is not satisfied
+  --> $DIR/defaulted-never-note.rs:27:5
+   |
+LL | fn foo<T: ImplementedForUnitButNotNever>(_t: T) {}
+   |    ---    ----------------------------- required by this bound in `foo`
+...
+LL |     foo(_x);
+   |     ^^^ the trait `ImplementedForUnitButNotNever` is not implemented for `!`
+   |
+   = note: the trait is implemented for `()`. Possibly this error has been caused by changes to Rust's type-inference algorithm (see: https://github.com/rust-lang/rust/issues/48950 for more info). Consider whether you meant to use the type `()` here instead.
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/never_type/dispatch_from_dyn_zst.rs b/src/test/ui/never_type/dispatch_from_dyn_zst.rs
new file mode 100644 (file)
index 0000000..764f58c
--- /dev/null
@@ -0,0 +1,51 @@
+// run-pass
+
+#![feature(unsize, dispatch_from_dyn, never_type)]
+
+#![allow(dead_code)]
+
+use std::{
+    ops::DispatchFromDyn,
+    marker::{Unsize, PhantomData},
+};
+
+struct Zst;
+struct NestedZst(PhantomData<()>, Zst);
+
+
+struct WithUnit<T: ?Sized>(Box<T>, ());
+impl<T: ?Sized, U: ?Sized> DispatchFromDyn<WithUnit<U>> for WithUnit<T>
+    where T: Unsize<U> {}
+
+struct WithPhantom<T: ?Sized>(Box<T>, PhantomData<()>);
+impl<T: ?Sized, U: ?Sized> DispatchFromDyn<WithPhantom<U>> for WithPhantom<T>
+    where T: Unsize<U> {}
+
+struct WithNever<T: ?Sized>(Box<T>, !);
+impl<T: ?Sized, U: ?Sized> DispatchFromDyn<WithNever<U>> for WithNever<T>
+    where T: Unsize<U> {}
+
+struct WithZst<T: ?Sized>(Box<T>, Zst);
+impl<T: ?Sized, U: ?Sized> DispatchFromDyn<WithZst<U>> for WithZst<T>
+    where T: Unsize<U> {}
+
+struct WithNestedZst<T: ?Sized>(Box<T>, NestedZst);
+impl<T: ?Sized, U: ?Sized> DispatchFromDyn<WithNestedZst<U>> for WithNestedZst<T>
+    where T: Unsize<U> {}
+
+
+struct Generic<T: ?Sized, A>(Box<T>, A);
+impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Generic<U, ()>> for Generic<T, ()>
+    where T: Unsize<U> {}
+impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Generic<U, PhantomData<()>>>
+    for Generic<T, PhantomData<()>>
+    where T: Unsize<U> {}
+impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Generic<U, !>> for Generic<T, !>
+    where T: Unsize<U> {}
+impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Generic<U, Zst>> for Generic<T, Zst>
+    where T: Unsize<U> {}
+impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Generic<U, NestedZst>> for Generic<T, NestedZst>
+    where T: Unsize<U> {}
+
+
+fn main() {}
diff --git a/src/test/ui/never_type/diverging-fallback-control-flow.rs b/src/test/ui/never_type/diverging-fallback-control-flow.rs
new file mode 100644 (file)
index 0000000..c68e636
--- /dev/null
@@ -0,0 +1,102 @@
+// run-pass
+
+#![allow(dead_code)]
+#![allow(unused_assignments)]
+#![allow(unused_variables)]
+#![allow(unreachable_code)]
+
+// Test various cases where we permit an unconstrained variable
+// to fallback based on control-flow.
+//
+// These represent current behavior, but are pretty dubious.  I would
+// like to revisit these and potentially change them. --nmatsakis
+
+#![feature(never_type)]
+
+trait BadDefault {
+    fn default() -> Self;
+}
+
+impl BadDefault for u32 {
+    fn default() -> Self {
+        0
+    }
+}
+
+impl BadDefault for ! {
+    fn default() -> ! {
+        panic!()
+    }
+}
+
+fn assignment() {
+    let x;
+
+    if true {
+        x = BadDefault::default();
+    } else {
+        x = return;
+    }
+}
+
+fn assignment_rev() {
+    let x;
+
+    if true {
+        x = return;
+    } else {
+        x = BadDefault::default();
+    }
+}
+
+fn if_then_else() {
+    let _x = if true {
+        BadDefault::default()
+    } else {
+        return;
+    };
+}
+
+fn if_then_else_rev() {
+    let _x = if true {
+        return;
+    } else {
+        BadDefault::default()
+    };
+}
+
+fn match_arm() {
+    let _x = match Ok(BadDefault::default()) {
+        Ok(v) => v,
+        Err(()) => return,
+    };
+}
+
+fn match_arm_rev() {
+    let _x = match Ok(BadDefault::default()) {
+        Err(()) => return,
+        Ok(v) => v,
+    };
+}
+
+fn loop_break() {
+    let _x = loop {
+        if false {
+            break return;
+        } else {
+            break BadDefault::default();
+        }
+    };
+}
+
+fn loop_break_rev() {
+    let _x = loop {
+        if false {
+            break return;
+        } else {
+            break BadDefault::default();
+        }
+    };
+}
+
+fn main() { }
diff --git a/src/test/ui/never_type/impl-for-never.rs b/src/test/ui/never_type/impl-for-never.rs
new file mode 100644 (file)
index 0000000..9423f08
--- /dev/null
@@ -0,0 +1,27 @@
+// run-pass
+
+#![feature(never_type)]
+
+// Test that we can call static methods on ! both directly and when it appears in a generic
+
+trait StringifyType {
+    fn stringify_type() -> &'static str;
+}
+
+impl StringifyType for ! {
+    fn stringify_type() -> &'static str {
+        "!"
+    }
+}
+
+fn maybe_stringify<T: StringifyType>(opt: Option<T>) -> &'static str {
+    match opt {
+        Some(_) => T::stringify_type(),
+        None => "none",
+    }
+}
+
+fn main() {
+    println!("! is {}", <!>::stringify_type());
+    println!("None is {}", maybe_stringify(None::<!>));
+}
diff --git a/src/test/ui/never_type/issue-13352.rs b/src/test/ui/never_type/issue-13352.rs
new file mode 100644 (file)
index 0000000..e6995be
--- /dev/null
@@ -0,0 +1,11 @@
+// ignore-cloudabi no std::process
+
+fn foo(_: Box<dyn FnMut()>) {}
+
+fn main() {
+    foo(loop {
+        std::process::exit(0);
+    });
+    2_usize + (loop {});
+    //~^ ERROR E0277
+}
diff --git a/src/test/ui/never_type/issue-13352.stderr b/src/test/ui/never_type/issue-13352.stderr
new file mode 100644 (file)
index 0000000..58ac74b
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0277]: cannot add `()` to `usize`
+  --> $DIR/issue-13352.rs:9:13
+   |
+LL |     2_usize + (loop {});
+   |             ^ no implementation for `usize + ()`
+   |
+   = help: the trait `std::ops::Add<()>` is not implemented for `usize`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/never_type/issue-2149.rs b/src/test/ui/never_type/issue-2149.rs
new file mode 100644 (file)
index 0000000..d46f0e6
--- /dev/null
@@ -0,0 +1,15 @@
+trait VecMonad<A> {
+    fn bind<B, F>(&self, f: F) where F: FnMut(A) -> Vec<B>;
+}
+
+impl<A> VecMonad<A> for Vec<A> {
+    fn bind<B, F>(&self, mut f: F) where F: FnMut(A) -> Vec<B> {
+        let mut r = panic!();
+        for elt in self { r = r + f(*elt); }
+        //~^ ERROR E0277
+   }
+}
+fn main() {
+    ["hi"].bind(|x| [x] );
+    //~^ ERROR no method named `bind` found for type `[&str; 1]` in the current scope
+}
diff --git a/src/test/ui/never_type/issue-2149.stderr b/src/test/ui/never_type/issue-2149.stderr
new file mode 100644 (file)
index 0000000..8ce2ba0
--- /dev/null
@@ -0,0 +1,22 @@
+error[E0277]: cannot add `std::vec::Vec<B>` to `()`
+  --> $DIR/issue-2149.rs:8:33
+   |
+LL |         for elt in self { r = r + f(*elt); }
+   |                                 ^ no implementation for `() + std::vec::Vec<B>`
+   |
+   = help: the trait `std::ops::Add<std::vec::Vec<B>>` is not implemented for `()`
+
+error[E0599]: no method named `bind` found for type `[&str; 1]` in the current scope
+  --> $DIR/issue-2149.rs:13:12
+   |
+LL |     ["hi"].bind(|x| [x] );
+   |            ^^^^ method not found in `[&str; 1]`
+   |
+   = help: items from traits can only be used if the trait is implemented and in scope
+   = note: the following trait defines an item `bind`, perhaps you need to implement it:
+           candidate #1: `VecMonad`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0599.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/never_type/issue-44402.rs b/src/test/ui/never_type/issue-44402.rs
new file mode 100644 (file)
index 0000000..699e480
--- /dev/null
@@ -0,0 +1,33 @@
+// check-pass
+
+#![allow(dead_code)]
+#![feature(never_type)]
+#![feature(exhaustive_patterns)]
+
+// Regression test for inhabitedness check. The old
+// cache used to cause us to incorrectly decide
+// that `test_b` was invalid.
+
+struct Foo {
+    field1: !,
+    field2: Option<&'static Bar>,
+}
+
+struct Bar {
+    field1: &'static Foo
+}
+
+fn test_a() {
+    let x: Option<Foo> = None;
+    match x { None => () }
+}
+
+fn test_b() {
+    let x: Option<Bar> = None;
+    match x {
+        Some(_) => (),
+        None => ()
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/never_type/never-assign-dead-code.rs b/src/test/ui/never_type/never-assign-dead-code.rs
new file mode 100644 (file)
index 0000000..7bb7c87
--- /dev/null
@@ -0,0 +1,12 @@
+// Test that an assignment of type ! makes the rest of the block dead code.
+
+// check-pass
+
+#![feature(never_type)]
+#![warn(unused)]
+
+fn main() {
+    let x: ! = panic!("aah"); //~ WARN unused
+    drop(x); //~ WARN unreachable
+    //~^ WARN unreachable
+}
diff --git a/src/test/ui/never_type/never-assign-dead-code.stderr b/src/test/ui/never_type/never-assign-dead-code.stderr
new file mode 100644 (file)
index 0000000..1860150
--- /dev/null
@@ -0,0 +1,37 @@
+warning: unreachable statement
+  --> $DIR/never-assign-dead-code.rs:10:5
+   |
+LL |     let x: ! = panic!("aah");
+   |                ------------- any code following this expression is unreachable
+LL |     drop(x);
+   |     ^^^^^^^^ unreachable statement
+   |
+note: lint level defined here
+  --> $DIR/never-assign-dead-code.rs:6:9
+   |
+LL | #![warn(unused)]
+   |         ^^^^^^
+   = note: `#[warn(unreachable_code)]` implied by `#[warn(unused)]`
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: unreachable call
+  --> $DIR/never-assign-dead-code.rs:10:5
+   |
+LL |     drop(x);
+   |     ^^^^ - any code following this expression is unreachable
+   |     |
+   |     unreachable call
+
+warning: unused variable: `x`
+  --> $DIR/never-assign-dead-code.rs:9:9
+   |
+LL |     let x: ! = panic!("aah");
+   |         ^ help: consider prefixing with an underscore: `_x`
+   |
+note: lint level defined here
+  --> $DIR/never-assign-dead-code.rs:6:9
+   |
+LL | #![warn(unused)]
+   |         ^^^^^^
+   = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
+
diff --git a/src/test/ui/never_type/never-assign-wrong-type.rs b/src/test/ui/never_type/never-assign-wrong-type.rs
new file mode 100644 (file)
index 0000000..67e26f5
--- /dev/null
@@ -0,0 +1,8 @@
+// Test that we can't use another type in place of !
+
+#![feature(never_type)]
+#![deny(warnings)]
+
+fn main() {
+    let x: ! = "hello"; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/never_type/never-assign-wrong-type.stderr b/src/test/ui/never_type/never-assign-wrong-type.stderr
new file mode 100644 (file)
index 0000000..da2e77d
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+  --> $DIR/never-assign-wrong-type.rs:7:16
+   |
+LL |     let x: ! = "hello";
+   |                ^^^^^^^ expected !, found reference
+   |
+   = note: expected type `!`
+              found type `&'static str`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/never_type/never-associated-type.rs b/src/test/ui/never_type/never-associated-type.rs
new file mode 100644 (file)
index 0000000..7f0a3fe
--- /dev/null
@@ -0,0 +1,24 @@
+// Test that we can use ! as an associated type.
+
+// run-fail
+// error-pattern:kapow!
+
+#![feature(never_type)]
+
+trait Foo {
+    type Wow;
+
+    fn smeg(&self) -> Self::Wow;
+}
+
+struct Blah;
+impl Foo for Blah {
+    type Wow = !;
+    fn smeg(&self) -> ! {
+        panic!("kapow!");
+    }
+}
+
+fn main() {
+    Blah.smeg();
+}
diff --git a/src/test/ui/never_type/never-from-impl-is-reserved.rs b/src/test/ui/never_type/never-from-impl-is-reserved.rs
new file mode 100644 (file)
index 0000000..9d16015
--- /dev/null
@@ -0,0 +1,12 @@
+// check that the `for<T> T: From<!>` impl is reserved
+
+#![feature(never_type)]
+
+pub struct MyFoo;
+pub trait MyTrait {}
+
+impl MyTrait for MyFoo {}
+// This will conflict with the first impl if we impl `for<T> T: From<!>`.
+impl<T> MyTrait for T where T: From<!> {} //~ ERROR conflicting implementation
+
+fn main() {}
diff --git a/src/test/ui/never_type/never-from-impl-is-reserved.stderr b/src/test/ui/never_type/never-from-impl-is-reserved.stderr
new file mode 100644 (file)
index 0000000..8b8d0f4
--- /dev/null
@@ -0,0 +1,14 @@
+error[E0119]: conflicting implementations of trait `MyTrait` for type `MyFoo`:
+  --> $DIR/never-from-impl-is-reserved.rs:10:1
+   |
+LL | impl MyTrait for MyFoo {}
+   | ---------------------- first implementation here
+LL | // This will conflict with the first impl if we impl `for<T> T: From<!>`.
+LL | impl<T> MyTrait for T where T: From<!> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyFoo`
+   |
+   = note: permitting this impl would forbid us from adding `impl<T> From<!> for T` later; see rust-lang/rust#64715 for details
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/never_type/never-result.rs b/src/test/ui/never_type/never-result.rs
new file mode 100644 (file)
index 0000000..35af379
--- /dev/null
@@ -0,0 +1,21 @@
+// run-pass
+
+#![allow(unused_variables)]
+#![allow(unreachable_code)]
+
+// Test that we can extract a ! through pattern matching then use it as several different types.
+
+#![feature(never_type)]
+
+fn main() {
+    let x: Result<u32, !> = Ok(123);
+    match x {
+        Ok(z) => (),
+        Err(y) => {
+            let q: u32 = y;
+            let w: i32 = y;
+            let e: String = y;
+            y
+        },
+    }
+}
diff --git a/src/test/ui/never_type/never-type-arg.rs b/src/test/ui/never_type/never-type-arg.rs
new file mode 100644 (file)
index 0000000..a82d351
--- /dev/null
@@ -0,0 +1,18 @@
+// Test that we can use ! as an argument to a trait impl.
+
+// run-fail
+// error-pattern:oh no!
+
+#![feature(never_type)]
+
+struct Wub;
+
+impl PartialEq<!> for Wub {
+    fn eq(&self, other: &!) -> bool {
+        *other
+    }
+}
+
+fn main() {
+    let _ = Wub == panic!("oh no!");
+}
diff --git a/src/test/ui/never_type/never-type-rvalues.rs b/src/test/ui/never_type/never-type-rvalues.rs
new file mode 100644 (file)
index 0000000..9ccc73d
--- /dev/null
@@ -0,0 +1,38 @@
+// run-pass
+
+#![feature(never_type)]
+#![allow(dead_code)]
+#![allow(path_statements)]
+#![allow(unreachable_patterns)]
+
+fn never_direct(x: !) {
+    x;
+}
+
+fn never_ref_pat(ref x: !) {
+    *x;
+}
+
+fn never_ref(x: &!) {
+    let &y = x;
+    y;
+}
+
+fn never_pointer(x: *const !) {
+    unsafe {
+        *x;
+    }
+}
+
+fn never_slice(x: &[!]) {
+    x[0];
+}
+
+fn never_match(x: Result<(), !>) {
+    match x {
+        Ok(_) => {},
+        Err(_) => {},
+    }
+}
+
+pub fn main() { }
diff --git a/src/test/ui/never_type/never_coercions.rs b/src/test/ui/never_type/never_coercions.rs
new file mode 100644 (file)
index 0000000..105c386
--- /dev/null
@@ -0,0 +1,12 @@
+// run-pass
+// Test that having something of type ! doesn't screw up type-checking and that it coerces to the
+// LUB type of the other match arms.
+
+fn main() {
+    let v: Vec<u32> = Vec::new();
+    match 0u32 {
+        0 => &v,
+        1 => return,
+        _ => &v[..],
+    };
+}
diff --git a/src/test/ui/never_type/never_transmute_never.rs b/src/test/ui/never_type/never_transmute_never.rs
new file mode 100644 (file)
index 0000000..fce3ced
--- /dev/null
@@ -0,0 +1,23 @@
+// check-pass
+
+#![crate_type="lib"]
+
+#![feature(never_type)]
+#![allow(dead_code)]
+#![allow(unreachable_code)]
+#![allow(unused_variables)]
+
+struct Foo;
+
+pub fn f(x: !) -> ! {
+    x
+}
+
+pub fn ub() {
+    // This is completely undefined behaviour,
+    // but we still want to make sure it compiles.
+    let x: ! = unsafe {
+        std::mem::transmute::<Foo, !>(Foo)
+    };
+    f(x)
+}
diff --git a/src/test/ui/never_type/panic-uninitialized-zeroed.rs b/src/test/ui/never_type/panic-uninitialized-zeroed.rs
new file mode 100644 (file)
index 0000000..b0d6629
--- /dev/null
@@ -0,0 +1,102 @@
+// run-pass
+// ignore-wasm32-bare always compiled as panic=abort right now and this requires unwinding
+// This test checks that instantiating an uninhabited type via `mem::{uninitialized,zeroed}` results
+// in a runtime panic.
+
+#![feature(never_type)]
+#![allow(deprecated, invalid_value)]
+
+use std::{mem, panic};
+
+#[allow(dead_code)]
+struct Foo {
+    x: u8,
+    y: !,
+}
+
+enum Bar {}
+
+fn main() {
+    unsafe {
+        assert_eq!(
+            panic::catch_unwind(|| {
+                mem::uninitialized::<!>()
+            }).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
+                s == "Attempted to instantiate uninhabited type !"
+            })),
+            Some(true)
+        );
+
+        assert_eq!(
+            panic::catch_unwind(|| {
+                mem::zeroed::<!>()
+            }).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
+                s == "Attempted to instantiate uninhabited type !"
+            })),
+            Some(true)
+        );
+
+        assert_eq!(
+            panic::catch_unwind(|| {
+                mem::MaybeUninit::<!>::uninit().assume_init()
+            }).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
+                s == "Attempted to instantiate uninhabited type !"
+            })),
+            Some(true)
+        );
+
+        assert_eq!(
+            panic::catch_unwind(|| {
+                mem::uninitialized::<Foo>()
+            }).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
+                s == "Attempted to instantiate uninhabited type Foo"
+            })),
+            Some(true)
+        );
+
+        assert_eq!(
+            panic::catch_unwind(|| {
+                mem::zeroed::<Foo>()
+            }).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
+                s == "Attempted to instantiate uninhabited type Foo"
+            })),
+            Some(true)
+        );
+
+        assert_eq!(
+            panic::catch_unwind(|| {
+                mem::MaybeUninit::<Foo>::uninit().assume_init()
+            }).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
+                s == "Attempted to instantiate uninhabited type Foo"
+            })),
+            Some(true)
+        );
+
+        assert_eq!(
+            panic::catch_unwind(|| {
+                mem::uninitialized::<Bar>()
+            }).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
+                s == "Attempted to instantiate uninhabited type Bar"
+            })),
+            Some(true)
+        );
+
+        assert_eq!(
+            panic::catch_unwind(|| {
+                mem::zeroed::<Bar>()
+            }).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
+                s == "Attempted to instantiate uninhabited type Bar"
+            })),
+            Some(true)
+        );
+
+        assert_eq!(
+            panic::catch_unwind(|| {
+                mem::MaybeUninit::<Bar>::uninit().assume_init()
+            }).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
+                s == "Attempted to instantiate uninhabited type Bar"
+            })),
+            Some(true)
+        );
+    }
+}
diff --git a/src/test/ui/never_type/try_from.rs b/src/test/ui/never_type/try_from.rs
new file mode 100644 (file)
index 0000000..5045157
--- /dev/null
@@ -0,0 +1,37 @@
+// run-pass
+// This test relies on `TryFrom` being blanket impl for all `T: Into`
+// and `TryInto` being blanket impl for all `U: TryFrom`
+
+// This test was added to show the motivation for doing this
+// over `TryFrom` being blanket impl for all `T: From`
+
+#![feature(never_type)]
+
+use std::convert::{TryInto, Infallible};
+
+struct Foo<T> {
+    t: T,
+}
+
+// This fails to compile due to coherence restrictions
+// as of Rust version 1.32.x, therefore it could not be used
+// instead of the `Into` version of the impl, and serves as
+// motivation for a blanket impl for all `T: Into`, instead
+// of a blanket impl for all `T: From`
+/*
+impl<T> From<Foo<T>> for Box<T> {
+    fn from(foo: Foo<T>) -> Box<T> {
+        Box::new(foo.t)
+    }
+}
+*/
+
+impl<T> Into<Vec<T>> for Foo<T> {
+    fn into(self) -> Vec<T> {
+        vec![self.t]
+    }
+}
+
+pub fn main() {
+    let _: Result<Vec<i32>, Infallible> = Foo { t: 10 }.try_into();
+}
diff --git a/src/test/ui/panic-uninitialized-zeroed.rs b/src/test/ui/panic-uninitialized-zeroed.rs
deleted file mode 100644 (file)
index b0d6629..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-// run-pass
-// ignore-wasm32-bare always compiled as panic=abort right now and this requires unwinding
-// This test checks that instantiating an uninhabited type via `mem::{uninitialized,zeroed}` results
-// in a runtime panic.
-
-#![feature(never_type)]
-#![allow(deprecated, invalid_value)]
-
-use std::{mem, panic};
-
-#[allow(dead_code)]
-struct Foo {
-    x: u8,
-    y: !,
-}
-
-enum Bar {}
-
-fn main() {
-    unsafe {
-        assert_eq!(
-            panic::catch_unwind(|| {
-                mem::uninitialized::<!>()
-            }).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
-                s == "Attempted to instantiate uninhabited type !"
-            })),
-            Some(true)
-        );
-
-        assert_eq!(
-            panic::catch_unwind(|| {
-                mem::zeroed::<!>()
-            }).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
-                s == "Attempted to instantiate uninhabited type !"
-            })),
-            Some(true)
-        );
-
-        assert_eq!(
-            panic::catch_unwind(|| {
-                mem::MaybeUninit::<!>::uninit().assume_init()
-            }).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
-                s == "Attempted to instantiate uninhabited type !"
-            })),
-            Some(true)
-        );
-
-        assert_eq!(
-            panic::catch_unwind(|| {
-                mem::uninitialized::<Foo>()
-            }).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
-                s == "Attempted to instantiate uninhabited type Foo"
-            })),
-            Some(true)
-        );
-
-        assert_eq!(
-            panic::catch_unwind(|| {
-                mem::zeroed::<Foo>()
-            }).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
-                s == "Attempted to instantiate uninhabited type Foo"
-            })),
-            Some(true)
-        );
-
-        assert_eq!(
-            panic::catch_unwind(|| {
-                mem::MaybeUninit::<Foo>::uninit().assume_init()
-            }).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
-                s == "Attempted to instantiate uninhabited type Foo"
-            })),
-            Some(true)
-        );
-
-        assert_eq!(
-            panic::catch_unwind(|| {
-                mem::uninitialized::<Bar>()
-            }).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
-                s == "Attempted to instantiate uninhabited type Bar"
-            })),
-            Some(true)
-        );
-
-        assert_eq!(
-            panic::catch_unwind(|| {
-                mem::zeroed::<Bar>()
-            }).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
-                s == "Attempted to instantiate uninhabited type Bar"
-            })),
-            Some(true)
-        );
-
-        assert_eq!(
-            panic::catch_unwind(|| {
-                mem::MaybeUninit::<Bar>::uninit().assume_init()
-            }).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
-                s == "Attempted to instantiate uninhabited type Bar"
-            })),
-            Some(true)
-        );
-    }
-}
diff --git a/src/test/ui/reachable/auxiliary/unreachable_variant.rs b/src/test/ui/reachable/auxiliary/unreachable_variant.rs
new file mode 100644 (file)
index 0000000..4e94a4b
--- /dev/null
@@ -0,0 +1,5 @@
+mod super_sekrit {
+    pub enum sooper_sekrit {
+        quux, baz
+    }
+}
diff --git a/src/test/ui/reachable/unreachable-arm.rs b/src/test/ui/reachable/unreachable-arm.rs
new file mode 100644 (file)
index 0000000..64c3896
--- /dev/null
@@ -0,0 +1,14 @@
+#![feature(box_patterns)]
+#![feature(box_syntax)]
+#![allow(dead_code)]
+#![deny(unreachable_patterns)]
+
+enum Foo { A(Box<Foo>, isize), B(usize), }
+
+fn main() {
+    match Foo::B(1) {
+        Foo::B(_) | Foo::A(box _, 1) => { }
+        Foo::A(_, 1) => { } //~ ERROR unreachable pattern
+        _ => { }
+    }
+}
diff --git a/src/test/ui/reachable/unreachable-arm.stderr b/src/test/ui/reachable/unreachable-arm.stderr
new file mode 100644 (file)
index 0000000..8e65745
--- /dev/null
@@ -0,0 +1,14 @@
+error: unreachable pattern
+  --> $DIR/unreachable-arm.rs:11:9
+   |
+LL |         Foo::A(_, 1) => { }
+   |         ^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/unreachable-arm.rs:4:9
+   |
+LL | #![deny(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/reachable/unreachable-code.rs b/src/test/ui/reachable/unreachable-code.rs
new file mode 100644 (file)
index 0000000..ad0dc8a
--- /dev/null
@@ -0,0 +1,8 @@
+#![deny(unreachable_code)]
+#![allow(unused_variables)]
+
+fn main() {
+  loop{}
+
+  let a = 3; //~ ERROR: unreachable statement
+}
diff --git a/src/test/ui/reachable/unreachable-code.stderr b/src/test/ui/reachable/unreachable-code.stderr
new file mode 100644 (file)
index 0000000..184440d
--- /dev/null
@@ -0,0 +1,17 @@
+error: unreachable statement
+  --> $DIR/unreachable-code.rs:7:3
+   |
+LL |   loop{}
+   |   ------ any code following this expression is unreachable
+LL | 
+LL |   let a = 3;
+   |   ^^^^^^^^^^ unreachable statement
+   |
+note: lint level defined here
+  --> $DIR/unreachable-code.rs:1:9
+   |
+LL | #![deny(unreachable_code)]
+   |         ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/reachable/unreachable-in-call.rs b/src/test/ui/reachable/unreachable-in-call.rs
new file mode 100644 (file)
index 0000000..dd94e79
--- /dev/null
@@ -0,0 +1,22 @@
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+
+fn diverge() -> ! { panic!() }
+
+fn get_u8() -> u8 {
+    1
+}
+fn call(_: u8, _: u8) {
+
+}
+fn diverge_first() {
+    call(diverge(),
+         get_u8()); //~ ERROR unreachable expression
+}
+fn diverge_second() {
+    call( //~ ERROR unreachable call
+        get_u8(),
+        diverge());
+}
+
+fn main() {}
diff --git a/src/test/ui/reachable/unreachable-in-call.stderr b/src/test/ui/reachable/unreachable-in-call.stderr
new file mode 100644 (file)
index 0000000..1d081d1
--- /dev/null
@@ -0,0 +1,25 @@
+error: unreachable expression
+  --> $DIR/unreachable-in-call.rs:14:10
+   |
+LL |     call(diverge(),
+   |          --------- any code following this expression is unreachable
+LL |          get_u8());
+   |          ^^^^^^^^ unreachable expression
+   |
+note: lint level defined here
+  --> $DIR/unreachable-in-call.rs:2:9
+   |
+LL | #![deny(unreachable_code)]
+   |         ^^^^^^^^^^^^^^^^
+
+error: unreachable call
+  --> $DIR/unreachable-in-call.rs:17:5
+   |
+LL |     call(
+   |     ^^^^ unreachable call
+LL |         get_u8(),
+LL |         diverge());
+   |         --------- any code following this expression is unreachable
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/reachable/unreachable-loop-patterns.rs b/src/test/ui/reachable/unreachable-loop-patterns.rs
new file mode 100644 (file)
index 0000000..6f1d2ef
--- /dev/null
@@ -0,0 +1,21 @@
+#![feature(never_type)]
+#![feature(exhaustive_patterns)]
+
+#![allow(unreachable_code)]
+#![deny(unreachable_patterns)]
+
+enum Void {}
+
+impl Iterator for Void {
+    type Item = Void;
+
+    fn next(&mut self) -> Option<Void> {
+        None
+    }
+}
+
+fn main() {
+    for _ in unimplemented!() as Void {}
+    //~^ ERROR unreachable pattern
+    //~^^ ERROR unreachable pattern
+}
diff --git a/src/test/ui/reachable/unreachable-loop-patterns.stderr b/src/test/ui/reachable/unreachable-loop-patterns.stderr
new file mode 100644 (file)
index 0000000..bb51033
--- /dev/null
@@ -0,0 +1,20 @@
+error: unreachable pattern
+  --> $DIR/unreachable-loop-patterns.rs:18:9
+   |
+LL |     for _ in unimplemented!() as Void {}
+   |         ^
+   |
+note: lint level defined here
+  --> $DIR/unreachable-loop-patterns.rs:5:9
+   |
+LL | #![deny(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/unreachable-loop-patterns.rs:18:14
+   |
+LL |     for _ in unimplemented!() as Void {}
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/reachable/unreachable-try-pattern.rs b/src/test/ui/reachable/unreachable-try-pattern.rs
new file mode 100644 (file)
index 0000000..23360e7
--- /dev/null
@@ -0,0 +1,41 @@
+// check-pass
+#![feature(never_type, exhaustive_patterns)]
+#![warn(unreachable_code)]
+#![warn(unreachable_patterns)]
+
+enum Void {}
+
+impl From<Void> for i32 {
+    fn from(v: Void) -> i32 {
+        match v {}
+    }
+}
+
+fn bar(x: Result<!, i32>) -> Result<u32, i32> {
+    x?
+}
+
+fn foo(x: Result<!, i32>) -> Result<u32, i32> {
+    let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?;
+    //~^ WARN unreachable pattern
+    //~| WARN unreachable expression
+    Ok(y)
+}
+
+fn qux(x: Result<u32, Void>) -> Result<u32, i32> {
+    Ok(x?)
+}
+
+fn vom(x: Result<u32, Void>) -> Result<u32, i32> {
+    let y = (match x { Ok(n) => Ok(n), Err(e) => Err(e) })?;
+    //~^ WARN unreachable pattern
+    Ok(y)
+}
+
+
+fn main() {
+    let _ = bar(Err(123));
+    let _ = foo(Err(123));
+    let _ = qux(Ok(123));
+    let _ = vom(Ok(123));
+}
diff --git a/src/test/ui/reachable/unreachable-try-pattern.stderr b/src/test/ui/reachable/unreachable-try-pattern.stderr
new file mode 100644 (file)
index 0000000..7070384
--- /dev/null
@@ -0,0 +1,33 @@
+warning: unreachable expression
+  --> $DIR/unreachable-try-pattern.rs:19:36
+   |
+LL |     let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?;
+   |                                    -^^^^^^^
+   |                                    |
+   |                                    unreachable expression
+   |                                    any code following this expression is unreachable
+   |
+note: lint level defined here
+  --> $DIR/unreachable-try-pattern.rs:3:9
+   |
+LL | #![warn(unreachable_code)]
+   |         ^^^^^^^^^^^^^^^^
+
+warning: unreachable pattern
+  --> $DIR/unreachable-try-pattern.rs:19:24
+   |
+LL |     let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?;
+   |                        ^^^^^
+   |
+note: lint level defined here
+  --> $DIR/unreachable-try-pattern.rs:4:9
+   |
+LL | #![warn(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+warning: unreachable pattern
+  --> $DIR/unreachable-try-pattern.rs:30:40
+   |
+LL |     let y = (match x { Ok(n) => Ok(n), Err(e) => Err(e) })?;
+   |                                        ^^^^^^
+
diff --git a/src/test/ui/reachable/unreachable-variant.rs b/src/test/ui/reachable/unreachable-variant.rs
new file mode 100644 (file)
index 0000000..008c2d4
--- /dev/null
@@ -0,0 +1,7 @@
+// aux-build:unreachable_variant.rs
+
+extern crate unreachable_variant as other;
+
+fn main() {
+    let _x = other::super_sekrit::sooper_sekrit::baz; //~ ERROR is private
+}
diff --git a/src/test/ui/reachable/unreachable-variant.stderr b/src/test/ui/reachable/unreachable-variant.stderr
new file mode 100644 (file)
index 0000000..276c77f
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0603]: module `super_sekrit` is private
+  --> $DIR/unreachable-variant.rs:6:21
+   |
+LL |     let _x = other::super_sekrit::sooper_sekrit::baz;
+   |                     ^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0603`.
diff --git a/src/test/ui/reachable/unwarned-match-on-never.rs b/src/test/ui/reachable/unwarned-match-on-never.rs
new file mode 100644 (file)
index 0000000..71f8fe3
--- /dev/null
@@ -0,0 +1,24 @@
+#![deny(unreachable_code)]
+#![allow(dead_code)]
+
+#![feature(never_type)]
+
+fn foo(x: !) -> bool {
+    // Explicit matches on the never type are unwarned.
+    match x {}
+    // But matches in unreachable code are warned.
+    match x {} //~ ERROR unreachable expression
+}
+
+fn bar() {
+    match (return) {
+        () => () //~ ERROR unreachable arm
+    }
+}
+
+fn main() {
+    return;
+    match () { //~ ERROR unreachable expression
+        () => (),
+    }
+}
diff --git a/src/test/ui/reachable/unwarned-match-on-never.stderr b/src/test/ui/reachable/unwarned-match-on-never.stderr
new file mode 100644 (file)
index 0000000..6b2fb4a
--- /dev/null
@@ -0,0 +1,35 @@
+error: unreachable expression
+  --> $DIR/unwarned-match-on-never.rs:10:5
+   |
+LL |     match x {}
+   |           - any code following this expression is unreachable
+LL |     // But matches in unreachable code are warned.
+LL |     match x {}
+   |     ^^^^^^^^^^ unreachable expression
+   |
+note: lint level defined here
+  --> $DIR/unwarned-match-on-never.rs:1:9
+   |
+LL | #![deny(unreachable_code)]
+   |         ^^^^^^^^^^^^^^^^
+
+error: unreachable arm
+  --> $DIR/unwarned-match-on-never.rs:15:15
+   |
+LL |     match (return) {
+   |           -------- any code following this expression is unreachable
+LL |         () => ()
+   |               ^^ unreachable arm
+
+error: unreachable expression
+  --> $DIR/unwarned-match-on-never.rs:21:5
+   |
+LL |       return;
+   |       ------ any code following this expression is unreachable
+LL | /     match () {
+LL | |         () => (),
+LL | |     }
+   | |_____^ unreachable expression
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/try_from.rs b/src/test/ui/try_from.rs
deleted file mode 100644 (file)
index 5045157..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// run-pass
-// This test relies on `TryFrom` being blanket impl for all `T: Into`
-// and `TryInto` being blanket impl for all `U: TryFrom`
-
-// This test was added to show the motivation for doing this
-// over `TryFrom` being blanket impl for all `T: From`
-
-#![feature(never_type)]
-
-use std::convert::{TryInto, Infallible};
-
-struct Foo<T> {
-    t: T,
-}
-
-// This fails to compile due to coherence restrictions
-// as of Rust version 1.32.x, therefore it could not be used
-// instead of the `Into` version of the impl, and serves as
-// motivation for a blanket impl for all `T: Into`, instead
-// of a blanket impl for all `T: From`
-/*
-impl<T> From<Foo<T>> for Box<T> {
-    fn from(foo: Foo<T>) -> Box<T> {
-        Box::new(foo.t)
-    }
-}
-*/
-
-impl<T> Into<Vec<T>> for Foo<T> {
-    fn into(self) -> Vec<T> {
-        vec![self.t]
-    }
-}
-
-pub fn main() {
-    let _: Result<Vec<i32>, Infallible> = Foo { t: 10 }.try_into();
-}
diff --git a/src/test/ui/uninhabited/always-inhabited-union-ref.rs b/src/test/ui/uninhabited/always-inhabited-union-ref.rs
new file mode 100644 (file)
index 0000000..11eae2a
--- /dev/null
@@ -0,0 +1,32 @@
+// The precise semantics of inhabitedness with respect to unions and references is currently
+// undecided. This test file currently checks a conservative choice.
+
+#![feature(exhaustive_patterns)]
+#![feature(never_type)]
+
+#![allow(dead_code)]
+#![allow(unreachable_code)]
+
+pub union Foo {
+    foo: !,
+}
+
+fn uninhab_ref() -> &'static ! {
+    unimplemented!()
+}
+
+fn uninhab_union() -> Foo {
+    unimplemented!()
+}
+
+fn match_on_uninhab() {
+    match uninhab_ref() {
+        //~^ ERROR non-exhaustive patterns: type `&'static !` is non-empty
+    }
+
+    match uninhab_union() {
+        //~^ ERROR non-exhaustive patterns: type `Foo` is non-empty
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/uninhabited/always-inhabited-union-ref.stderr b/src/test/ui/uninhabited/always-inhabited-union-ref.stderr
new file mode 100644 (file)
index 0000000..792ab6f
--- /dev/null
@@ -0,0 +1,19 @@
+error[E0004]: non-exhaustive patterns: type `&'static !` is non-empty
+  --> $DIR/always-inhabited-union-ref.rs:23:11
+   |
+LL |     match uninhab_ref() {
+   |           ^^^^^^^^^^^^^
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error[E0004]: non-exhaustive patterns: type `Foo` is non-empty
+  --> $DIR/always-inhabited-union-ref.rs:27:11
+   |
+LL |     match uninhab_union() {
+   |           ^^^^^^^^^^^^^^^
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/unreachable/auxiliary/unreachable_variant.rs b/src/test/ui/unreachable/auxiliary/unreachable_variant.rs
deleted file mode 100644 (file)
index 4e94a4b..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-mod super_sekrit {
-    pub enum sooper_sekrit {
-        quux, baz
-    }
-}
diff --git a/src/test/ui/unreachable/unreachable-arm.rs b/src/test/ui/unreachable/unreachable-arm.rs
deleted file mode 100644 (file)
index 64c3896..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#![feature(box_patterns)]
-#![feature(box_syntax)]
-#![allow(dead_code)]
-#![deny(unreachable_patterns)]
-
-enum Foo { A(Box<Foo>, isize), B(usize), }
-
-fn main() {
-    match Foo::B(1) {
-        Foo::B(_) | Foo::A(box _, 1) => { }
-        Foo::A(_, 1) => { } //~ ERROR unreachable pattern
-        _ => { }
-    }
-}
diff --git a/src/test/ui/unreachable/unreachable-arm.stderr b/src/test/ui/unreachable/unreachable-arm.stderr
deleted file mode 100644 (file)
index 8e65745..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-error: unreachable pattern
-  --> $DIR/unreachable-arm.rs:11:9
-   |
-LL |         Foo::A(_, 1) => { }
-   |         ^^^^^^^^^^^^
-   |
-note: lint level defined here
-  --> $DIR/unreachable-arm.rs:4:9
-   |
-LL | #![deny(unreachable_patterns)]
-   |         ^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/unreachable/unreachable-code.rs b/src/test/ui/unreachable/unreachable-code.rs
deleted file mode 100644 (file)
index ad0dc8a..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#![deny(unreachable_code)]
-#![allow(unused_variables)]
-
-fn main() {
-  loop{}
-
-  let a = 3; //~ ERROR: unreachable statement
-}
diff --git a/src/test/ui/unreachable/unreachable-code.stderr b/src/test/ui/unreachable/unreachable-code.stderr
deleted file mode 100644 (file)
index 184440d..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-error: unreachable statement
-  --> $DIR/unreachable-code.rs:7:3
-   |
-LL |   loop{}
-   |   ------ any code following this expression is unreachable
-LL | 
-LL |   let a = 3;
-   |   ^^^^^^^^^^ unreachable statement
-   |
-note: lint level defined here
-  --> $DIR/unreachable-code.rs:1:9
-   |
-LL | #![deny(unreachable_code)]
-   |         ^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/unreachable/unreachable-in-call.rs b/src/test/ui/unreachable/unreachable-in-call.rs
deleted file mode 100644 (file)
index dd94e79..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#![allow(dead_code)]
-#![deny(unreachable_code)]
-
-fn diverge() -> ! { panic!() }
-
-fn get_u8() -> u8 {
-    1
-}
-fn call(_: u8, _: u8) {
-
-}
-fn diverge_first() {
-    call(diverge(),
-         get_u8()); //~ ERROR unreachable expression
-}
-fn diverge_second() {
-    call( //~ ERROR unreachable call
-        get_u8(),
-        diverge());
-}
-
-fn main() {}
diff --git a/src/test/ui/unreachable/unreachable-in-call.stderr b/src/test/ui/unreachable/unreachable-in-call.stderr
deleted file mode 100644 (file)
index 1d081d1..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-error: unreachable expression
-  --> $DIR/unreachable-in-call.rs:14:10
-   |
-LL |     call(diverge(),
-   |          --------- any code following this expression is unreachable
-LL |          get_u8());
-   |          ^^^^^^^^ unreachable expression
-   |
-note: lint level defined here
-  --> $DIR/unreachable-in-call.rs:2:9
-   |
-LL | #![deny(unreachable_code)]
-   |         ^^^^^^^^^^^^^^^^
-
-error: unreachable call
-  --> $DIR/unreachable-in-call.rs:17:5
-   |
-LL |     call(
-   |     ^^^^ unreachable call
-LL |         get_u8(),
-LL |         diverge());
-   |         --------- any code following this expression is unreachable
-
-error: aborting due to 2 previous errors
-
diff --git a/src/test/ui/unreachable/unreachable-loop-patterns.rs b/src/test/ui/unreachable/unreachable-loop-patterns.rs
deleted file mode 100644 (file)
index 56ab1a2..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// compile-fail
-
-#![feature(never_type)]
-#![feature(exhaustive_patterns)]
-
-#![allow(unreachable_code)]
-#![deny(unreachable_patterns)]
-
-enum Void {}
-
-impl Iterator for Void {
-    type Item = Void;
-
-    fn next(&mut self) -> Option<Void> {
-        None
-    }
-}
-
-fn main() {
-    for _ in unimplemented!() as Void {}
-    //~^ ERROR unreachable pattern
-    //~^^ ERROR unreachable pattern
-}
diff --git a/src/test/ui/unreachable/unreachable-loop-patterns.stderr b/src/test/ui/unreachable/unreachable-loop-patterns.stderr
deleted file mode 100644 (file)
index 254d117..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-error: unreachable pattern
-  --> $DIR/unreachable-loop-patterns.rs:20:9
-   |
-LL |     for _ in unimplemented!() as Void {}
-   |         ^
-   |
-note: lint level defined here
-  --> $DIR/unreachable-loop-patterns.rs:7:9
-   |
-LL | #![deny(unreachable_patterns)]
-   |         ^^^^^^^^^^^^^^^^^^^^
-
-error: unreachable pattern
-  --> $DIR/unreachable-loop-patterns.rs:20:14
-   |
-LL |     for _ in unimplemented!() as Void {}
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
-
diff --git a/src/test/ui/unreachable/unreachable-try-pattern.rs b/src/test/ui/unreachable/unreachable-try-pattern.rs
deleted file mode 100644 (file)
index cbc5fce..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-// build-pass (FIXME(62277): could be check-pass?)
-#![feature(never_type, exhaustive_patterns)]
-#![warn(unreachable_code)]
-#![warn(unreachable_patterns)]
-
-enum Void {}
-
-impl From<Void> for i32 {
-    fn from(v: Void) -> i32 {
-        match v {}
-    }
-}
-
-fn bar(x: Result<!, i32>) -> Result<u32, i32> {
-    x?
-}
-
-fn foo(x: Result<!, i32>) -> Result<u32, i32> {
-    let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?;
-    //~^ WARN unreachable pattern
-    //~| WARN unreachable expression
-    Ok(y)
-}
-
-fn qux(x: Result<u32, Void>) -> Result<u32, i32> {
-    Ok(x?)
-}
-
-fn vom(x: Result<u32, Void>) -> Result<u32, i32> {
-    let y = (match x { Ok(n) => Ok(n), Err(e) => Err(e) })?;
-    //~^ WARN unreachable pattern
-    Ok(y)
-}
-
-
-fn main() {
-    let _ = bar(Err(123));
-    let _ = foo(Err(123));
-    let _ = qux(Ok(123));
-    let _ = vom(Ok(123));
-}
diff --git a/src/test/ui/unreachable/unreachable-try-pattern.stderr b/src/test/ui/unreachable/unreachable-try-pattern.stderr
deleted file mode 100644 (file)
index 7070384..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-warning: unreachable expression
-  --> $DIR/unreachable-try-pattern.rs:19:36
-   |
-LL |     let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?;
-   |                                    -^^^^^^^
-   |                                    |
-   |                                    unreachable expression
-   |                                    any code following this expression is unreachable
-   |
-note: lint level defined here
-  --> $DIR/unreachable-try-pattern.rs:3:9
-   |
-LL | #![warn(unreachable_code)]
-   |         ^^^^^^^^^^^^^^^^
-
-warning: unreachable pattern
-  --> $DIR/unreachable-try-pattern.rs:19:24
-   |
-LL |     let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?;
-   |                        ^^^^^
-   |
-note: lint level defined here
-  --> $DIR/unreachable-try-pattern.rs:4:9
-   |
-LL | #![warn(unreachable_patterns)]
-   |         ^^^^^^^^^^^^^^^^^^^^
-
-warning: unreachable pattern
-  --> $DIR/unreachable-try-pattern.rs:30:40
-   |
-LL |     let y = (match x { Ok(n) => Ok(n), Err(e) => Err(e) })?;
-   |                                        ^^^^^^
-
diff --git a/src/test/ui/unreachable/unreachable-variant.rs b/src/test/ui/unreachable/unreachable-variant.rs
deleted file mode 100644 (file)
index 008c2d4..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// aux-build:unreachable_variant.rs
-
-extern crate unreachable_variant as other;
-
-fn main() {
-    let _x = other::super_sekrit::sooper_sekrit::baz; //~ ERROR is private
-}
diff --git a/src/test/ui/unreachable/unreachable-variant.stderr b/src/test/ui/unreachable/unreachable-variant.stderr
deleted file mode 100644 (file)
index 276c77f..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0603]: module `super_sekrit` is private
-  --> $DIR/unreachable-variant.rs:6:21
-   |
-LL |     let _x = other::super_sekrit::sooper_sekrit::baz;
-   |                     ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0603`.
diff --git a/src/test/ui/unreachable/unwarned-match-on-never.rs b/src/test/ui/unreachable/unwarned-match-on-never.rs
deleted file mode 100644 (file)
index 71f8fe3..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#![deny(unreachable_code)]
-#![allow(dead_code)]
-
-#![feature(never_type)]
-
-fn foo(x: !) -> bool {
-    // Explicit matches on the never type are unwarned.
-    match x {}
-    // But matches in unreachable code are warned.
-    match x {} //~ ERROR unreachable expression
-}
-
-fn bar() {
-    match (return) {
-        () => () //~ ERROR unreachable arm
-    }
-}
-
-fn main() {
-    return;
-    match () { //~ ERROR unreachable expression
-        () => (),
-    }
-}
diff --git a/src/test/ui/unreachable/unwarned-match-on-never.stderr b/src/test/ui/unreachable/unwarned-match-on-never.stderr
deleted file mode 100644 (file)
index 6b2fb4a..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-error: unreachable expression
-  --> $DIR/unwarned-match-on-never.rs:10:5
-   |
-LL |     match x {}
-   |           - any code following this expression is unreachable
-LL |     // But matches in unreachable code are warned.
-LL |     match x {}
-   |     ^^^^^^^^^^ unreachable expression
-   |
-note: lint level defined here
-  --> $DIR/unwarned-match-on-never.rs:1:9
-   |
-LL | #![deny(unreachable_code)]
-   |         ^^^^^^^^^^^^^^^^
-
-error: unreachable arm
-  --> $DIR/unwarned-match-on-never.rs:15:15
-   |
-LL |     match (return) {
-   |           -------- any code following this expression is unreachable
-LL |         () => ()
-   |               ^^ unreachable arm
-
-error: unreachable expression
-  --> $DIR/unwarned-match-on-never.rs:21:5
-   |
-LL |       return;
-   |       ------ any code following this expression is unreachable
-LL | /     match () {
-LL | |         () => (),
-LL | |     }
-   | |_____^ unreachable expression
-
-error: aborting due to 3 previous errors
-