+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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!"))
-}
+++ /dev/null
-// 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;
-}
+++ /dev/null
-// 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();
-}
+++ /dev/null
-// 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!");
-}
+++ /dev/null
-// 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() {}
+++ /dev/null
-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`.
+++ /dev/null
-// Test that we can't pass other types for !
-
-#![feature(never_type)]
-
-fn foo(x: !) -> ! {
- x
-}
-
-fn main() {
- foo("wow"); //~ ERROR mismatched types
-}
+++ /dev/null
-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`.
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
#![feature(never_type)]
#![allow(unreachable_code)]
+++ /dev/null
-// 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();
-}
+++ /dev/null
-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`.
+++ /dev/null
-// 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() {}
+++ /dev/null
-// 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() { }
#![feature(never_type)]
+
fn foo() -> Result<u32, !> {
Ok(123)
}
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
// run-pass
+
#![allow(unreachable_code)]
#![feature(never_type)]
+++ /dev/null
-// 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::<!>));
-}
+++ /dev/null
-// ignore-cloudabi no std::process
-
-fn foo(_: Box<dyn FnMut()>) {}
-
-fn main() {
- foo(loop {
- std::process::exit(0);
- });
- 2_usize + (loop {});
- //~^ ERROR E0277
-}
+++ /dev/null
-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`.
+++ /dev/null
-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
-}
+++ /dev/null
-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`.
+++ /dev/null
-// 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() { }
#![feature(never_type)]
-
#![deny(unused_must_use)]
#[must_use]
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();
| ^^^^^^
+++ /dev/null
-// 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
-}
+++ /dev/null
-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)]`
-
+++ /dev/null
-// Test that we can't use another type in place of !
-
-#![feature(never_type)]
-#![deny(warnings)]
-
-fn main() {
- let x: ! = "hello"; //~ ERROR mismatched types
-}
+++ /dev/null
-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`.
+++ /dev/null
-// 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() {}
+++ /dev/null
-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`.
+++ /dev/null
-// 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
- },
- }
-}
+++ /dev/null
-// 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() { }
+++ /dev/null
-// 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[..],
- };
-}
+++ /dev/null
-// 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)
-}
--- /dev/null
+// 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;
+}
--- /dev/null
+// Test that we can't pass other types for !
+
+#![feature(never_type)]
+
+fn foo(x: !) -> ! {
+ x
+}
+
+fn main() {
+ foo("wow"); //~ ERROR mismatched types
+}
--- /dev/null
+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`.
--- /dev/null
+// 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!"))
+}
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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();
+}
--- /dev/null
+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`.
--- /dev/null
+// 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() {}
--- /dev/null
+// 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() { }
--- /dev/null
+// 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::<!>));
+}
--- /dev/null
+// ignore-cloudabi no std::process
+
+fn foo(_: Box<dyn FnMut()>) {}
+
+fn main() {
+ foo(loop {
+ std::process::exit(0);
+ });
+ 2_usize + (loop {});
+ //~^ ERROR E0277
+}
--- /dev/null
+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`.
--- /dev/null
+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
+}
--- /dev/null
+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`.
--- /dev/null
+// 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() { }
--- /dev/null
+// 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
+}
--- /dev/null
+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)]`
+
--- /dev/null
+// Test that we can't use another type in place of !
+
+#![feature(never_type)]
+#![deny(warnings)]
+
+fn main() {
+ let x: ! = "hello"; //~ ERROR mismatched types
+}
--- /dev/null
+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`.
--- /dev/null
+// 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();
+}
--- /dev/null
+// 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() {}
--- /dev/null
+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`.
--- /dev/null
+// 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
+ },
+ }
+}
--- /dev/null
+// 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!");
+}
--- /dev/null
+// 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() { }
--- /dev/null
+// 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[..],
+ };
+}
--- /dev/null
+// 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)
+}
--- /dev/null
+// 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)
+ );
+ }
+}
--- /dev/null
+// 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();
+}
+++ /dev/null
-// 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)
- );
- }
-}
--- /dev/null
+mod super_sekrit {
+ pub enum sooper_sekrit {
+ quux, baz
+ }
+}
--- /dev/null
+#![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
+ _ => { }
+ }
+}
--- /dev/null
+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
+
--- /dev/null
+#![deny(unreachable_code)]
+#![allow(unused_variables)]
+
+fn main() {
+ loop{}
+
+ let a = 3; //~ ERROR: unreachable statement
+}
--- /dev/null
+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
+
--- /dev/null
+#![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() {}
--- /dev/null
+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
+
--- /dev/null
+#![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
+}
--- /dev/null
+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
+
--- /dev/null
+// 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));
+}
--- /dev/null
+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) })?;
+ | ^^^^^^
+
--- /dev/null
+// aux-build:unreachable_variant.rs
+
+extern crate unreachable_variant as other;
+
+fn main() {
+ let _x = other::super_sekrit::sooper_sekrit::baz; //~ ERROR is private
+}
--- /dev/null
+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`.
--- /dev/null
+#![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
+ () => (),
+ }
+}
--- /dev/null
+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
+
+++ /dev/null
-// 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();
-}
--- /dev/null
+// 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() {}
--- /dev/null
+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`.
+++ /dev/null
-mod super_sekrit {
- pub enum sooper_sekrit {
- quux, baz
- }
-}
+++ /dev/null
-#![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
- _ => { }
- }
-}
+++ /dev/null
-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
-
+++ /dev/null
-#![deny(unreachable_code)]
-#![allow(unused_variables)]
-
-fn main() {
- loop{}
-
- let a = 3; //~ ERROR: unreachable statement
-}
+++ /dev/null
-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
-
+++ /dev/null
-#![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() {}
+++ /dev/null
-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
-
+++ /dev/null
-// 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
-}
+++ /dev/null
-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
-
+++ /dev/null
-// 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));
-}
+++ /dev/null
-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) })?;
- | ^^^^^^
-
+++ /dev/null
-// aux-build:unreachable_variant.rs
-
-extern crate unreachable_variant as other;
-
-fn main() {
- let _x = other::super_sekrit::sooper_sekrit::baz; //~ ERROR is private
-}
+++ /dev/null
-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`.
+++ /dev/null
-#![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
- () => (),
- }
-}
+++ /dev/null
-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
-