Rollup merge of #149541 - WaffleLapkin:never-test, r=lcnr

Various never type test improvements

I want to make sure that the never type ui tests are actually sensible, and to do so I'm trying to clean them up. This mainly adds comments explaining test purposes and removes outdated stuff.

I imagine best reviewed commit-by-commit, I tried to write useful descriptions and group things into small commits.

cc `@lcnr` (I removed `fallback`/`nofallback` terminology in b5f82d4716d0d978b89034c902f88e2d449da636)
This commit is contained in:
Matthias Krüger 2025-12-03 13:05:15 +01:00 committed by GitHub
commit a2aa4f08da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
65 changed files with 519 additions and 731 deletions

View file

@ -941,6 +941,8 @@ Contains a single test. It imports a massive amount of very similar types from a
## `tests/ui/never_type/`
Tests relating to the never type. Most tests are specifically about the never type fallback behavior.
See [Tracking issue for promoting `!` to a type (RFC 1216) #35121](https://github.com/rust-lang/rust/issues/35121).
## `tests/ui/new-range/`

View file

@ -0,0 +1,19 @@
error[E0277]: the trait bound `(): std::error::Error` is not satisfied
--> $DIR/coerce-issue-49593-box-never.rs:28:5
|
LL | Box::new(x)
| ^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
|
= note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>`
error[E0277]: the trait bound `(): std::error::Error` is not satisfied
--> $DIR/coerce-issue-49593-box-never.rs:33:5
|
LL | raw_ptr(x)
| ^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
|
= note: required for the cast from `*mut ()` to `*mut (dyn std::error::Error + 'static)`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.

View file

@ -1,57 +1,37 @@
//@ revisions: nofallback fallback
//@[fallback] edition: 2024
//@[fallback] check-pass
// Regression test for <https://github.com/rust-lang/rust/issues/49593>.
//
// This checks that we can construct `Box<dyn Error>` by calling `Box::new`
// with a value of the never type. And similarly for raw pointers.
//
// This used to fail because we tried to coerce `! -> dyn Error`, which then
// failed because we were trying to pass an unsized value by value, etc.
//
// On edition <= 2021 this currently fails because of never type fallback to
// unit.
//
//@ revisions: e2021 e2024
//@[e2021] edition: 2021
//@[e2024] edition: 2024
//
//@[e2024] check-pass
#![feature(never_type)]
use std::error::Error;
use std::mem;
fn raw_ptr_box<T>(t: T) -> *mut T {
fn raw_ptr<T>(t: T) -> *mut T {
panic!()
}
fn foo(x: !) -> Box<dyn Error> {
// Method resolution will generate new inference vars and relate them.
// Thus fallback will not fall back to `!`, but `()` instead.
Box::<_ /* ! */>::new(x)
//[nofallback]~^ ERROR trait bound `(): std::error::Error` is not satisfied
Box::new(x)
//[e2021]~^ ERROR trait bound `(): std::error::Error` is not satisfied
}
fn foo_raw_ptr(x: !) -> *mut dyn Error {
/* *mut $0 is coerced to *mut Error here */
raw_ptr_box::<_ /* ! */>(x)
//[nofallback]~^ ERROR trait bound `(): std::error::Error` is not satisfied
}
fn no_coercion(d: *mut dyn Error) -> *mut dyn Error {
/* an unsize coercion won't compile here, and it is indeed not used
because there is nothing requiring the _ to be Sized */
d as *mut _
}
trait Xyz {}
struct S;
struct T;
impl Xyz for S {}
impl Xyz for T {}
fn foo_no_never() {
let mut x /* : Option<S> */ = None;
let mut first_iter = false;
loop {
if !first_iter {
let y: Box<dyn Xyz>
= /* Box<$0> is coerced to Box<Xyz> here */ Box::new(x.unwrap());
}
x = Some(S);
first_iter = true;
}
let mut y: Option<S> = None;
// assert types are equal
mem::swap(&mut x, &mut y);
raw_ptr(x)
//[e2021]~^ ERROR trait bound `(): std::error::Error` is not satisfied
}
fn main() {}

View file

@ -1,79 +0,0 @@
#![feature(never_type)]
fn foo(x: usize, y: !, z: usize) { }
fn call_foo_a() {
foo(return, 22, 44);
//~^ ERROR mismatched types
}
fn call_foo_b() {
// Divergence happens in the argument itself, definitely ok.
foo(22, return, 44);
}
fn call_foo_c() {
// This test fails because the divergence happens **after** the
// coercion to `!`:
foo(22, 44, return); //~ ERROR mismatched types
}
fn call_foo_d() {
// This test passes because `a` has type `!`:
let a: ! = return;
let b = 22;
let c = 44;
foo(a, b, c); // ... and hence a reference to `a` is expected to diverge.
//~^ ERROR mismatched types
}
fn call_foo_e() {
// This test probably could pass but we don't *know* that `a`
// has type `!` so we don't let it work.
let a = return;
let b = 22;
let c = 44;
foo(a, b, c); //~ ERROR mismatched types
}
fn call_foo_f() {
// This fn fails because `a` has type `usize`, and hence a
// reference to is it **not** considered to diverge.
let a: usize = return;
let b = 22;
let c = 44;
foo(a, b, c); //~ ERROR mismatched types
}
fn array_a() {
// Return is coerced to `!` just fine, but `22` cannot be.
let x: [!; 2] = [return, 22]; //~ ERROR mismatched types
}
fn array_b() {
// Error: divergence has not yet occurred.
let x: [!; 2] = [22, return]; //~ ERROR mismatched types
}
fn tuple_a() {
// No divergence at all.
let x: (usize, !, usize) = (22, 44, 66); //~ ERROR mismatched types
}
fn tuple_b() {
// Divergence happens before coercion: OK
let x: (usize, !, usize) = (return, 44, 66);
//~^ ERROR mismatched types
}
fn tuple_c() {
// Divergence happens before coercion: OK
let x: (usize, !, usize) = (22, return, 66);
}
fn tuple_d() {
// Error: divergence happens too late
let x: (usize, !, usize) = (22, 44, return); //~ ERROR mismatched types
}
fn main() { }

View file

@ -1,130 +0,0 @@
error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:6:17
|
LL | foo(return, 22, 44);
| --- ^^ expected `!`, found integer
| |
| arguments to this function are incorrect
|
= note: expected type `!`
found type `{integer}`
note: function defined here
--> $DIR/coerce-to-bang.rs:3:4
|
LL | fn foo(x: usize, y: !, z: usize) { }
| ^^^ ----
error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:18:13
|
LL | foo(22, 44, return);
| --- ^^ expected `!`, found integer
| |
| arguments to this function are incorrect
|
= note: expected type `!`
found type `{integer}`
note: function defined here
--> $DIR/coerce-to-bang.rs:3:4
|
LL | fn foo(x: usize, y: !, z: usize) { }
| ^^^ ----
error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:26:12
|
LL | foo(a, b, c); // ... and hence a reference to `a` is expected to diverge.
| --- ^ expected `!`, found integer
| |
| arguments to this function are incorrect
|
= note: expected type `!`
found type `{integer}`
note: function defined here
--> $DIR/coerce-to-bang.rs:3:4
|
LL | fn foo(x: usize, y: !, z: usize) { }
| ^^^ ----
error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:36:12
|
LL | foo(a, b, c);
| --- ^ expected `!`, found integer
| |
| arguments to this function are incorrect
|
= note: expected type `!`
found type `{integer}`
note: function defined here
--> $DIR/coerce-to-bang.rs:3:4
|
LL | fn foo(x: usize, y: !, z: usize) { }
| ^^^ ----
error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:45:12
|
LL | foo(a, b, c);
| --- ^ expected `!`, found integer
| |
| arguments to this function are incorrect
|
= note: expected type `!`
found type `{integer}`
note: function defined here
--> $DIR/coerce-to-bang.rs:3:4
|
LL | fn foo(x: usize, y: !, z: usize) { }
| ^^^ ----
error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:50:21
|
LL | let x: [!; 2] = [return, 22];
| ------ ^^^^^^^^^^^^ expected `[!; 2]`, found `[{integer}; 2]`
| |
| expected due to this
|
= note: expected array `[!; 2]`
found array `[{integer}; 2]`
error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:55:22
|
LL | let x: [!; 2] = [22, return];
| ^^ expected `!`, found integer
|
= note: expected type `!`
found type `{integer}`
error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:60:37
|
LL | let x: (usize, !, usize) = (22, 44, 66);
| ^^ expected `!`, found integer
|
= note: expected type `!`
found type `{integer}`
error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:65:41
|
LL | let x: (usize, !, usize) = (return, 44, 66);
| ^^ expected `!`, found integer
|
= note: expected type `!`
found type `{integer}`
error[E0308]: mismatched types
--> $DIR/coerce-to-bang.rs:76:37
|
LL | let x: (usize, !, usize) = (22, 44, return);
| ^^ expected `!`, found integer
|
= note: expected type `!`
found type `{integer}`
error: aborting due to 10 previous errors
For more information about this error, try `rustc --explain E0308`.

View file

@ -1,3 +1,7 @@
// This is a test for various ways in which the change to the never type
// fallback can break things and for the `dependency_on_unit_never_type_fallback`
// lint.
//
//@ revisions: e2021 e2024
//
//@[e2021] edition: 2021

View file

@ -1,5 +1,5 @@
error: this function depends on never type fallback being `()`
--> $DIR/never-type-fallback-breaking.rs:16:1
--> $DIR/never-type-fallback-breaking.rs:20:1
|
LL | fn m() {
| ^^^^^^
@ -8,7 +8,7 @@ LL | fn m() {
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:20:17
--> $DIR/never-type-fallback-breaking.rs:24:17
|
LL | true => Default::default(),
| ^^^^^^^^^^^^^^^^^^
@ -19,7 +19,7 @@ LL | let x: () = match true {
| ++++
error: this function depends on never type fallback being `()`
--> $DIR/never-type-fallback-breaking.rs:28:1
--> $DIR/never-type-fallback-breaking.rs:32:1
|
LL | fn q() -> Option<()> {
| ^^^^^^^^^^^^^^^^^^^^
@ -28,7 +28,7 @@ LL | fn q() -> Option<()> {
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:35:5
--> $DIR/never-type-fallback-breaking.rs:39:5
|
LL | deserialize()?;
| ^^^^^^^^^^^^^
@ -38,7 +38,7 @@ LL | deserialize::<()>()?;
| ++++++
error: this function depends on never type fallback being `()`
--> $DIR/never-type-fallback-breaking.rs:45:1
--> $DIR/never-type-fallback-breaking.rs:49:1
|
LL | fn meow() -> Result<(), ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -47,7 +47,7 @@ LL | fn meow() -> Result<(), ()> {
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `(): From<!>` will fail
--> $DIR/never-type-fallback-breaking.rs:48:5
--> $DIR/never-type-fallback-breaking.rs:52:5
|
LL | help(1)?;
| ^^^^^^^
@ -57,7 +57,7 @@ LL | help::<(), _>(1)?;
| +++++++++
error: this function depends on never type fallback being `()`
--> $DIR/never-type-fallback-breaking.rs:57:1
--> $DIR/never-type-fallback-breaking.rs:61:1
|
LL | pub fn fallback_return() -> Result<(), ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -66,7 +66,7 @@ LL | pub fn fallback_return() -> Result<(), ()> {
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:60:19
--> $DIR/never-type-fallback-breaking.rs:64:19
|
LL | takes_apit(|| Default::default())?;
| ^^^^^^^^^^^^^^^^^^
@ -76,7 +76,7 @@ LL | takes_apit::<()>(|| Default::default())?;
| ++++++
error: this function depends on never type fallback being `()`
--> $DIR/never-type-fallback-breaking.rs:71:1
--> $DIR/never-type-fallback-breaking.rs:75:1
|
LL | fn fully_apit() -> Result<(), ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -85,7 +85,7 @@ LL | fn fully_apit() -> Result<(), ()> {
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:74:17
--> $DIR/never-type-fallback-breaking.rs:78:17
|
LL | takes_apit2(mk()?);
| ^^^^^
@ -98,7 +98,7 @@ error: aborting due to 5 previous errors
Future incompatibility report: Future breakage diagnostic:
error: this function depends on never type fallback being `()`
--> $DIR/never-type-fallback-breaking.rs:16:1
--> $DIR/never-type-fallback-breaking.rs:20:1
|
LL | fn m() {
| ^^^^^^
@ -107,7 +107,7 @@ LL | fn m() {
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:20:17
--> $DIR/never-type-fallback-breaking.rs:24:17
|
LL | true => Default::default(),
| ^^^^^^^^^^^^^^^^^^
@ -119,7 +119,7 @@ LL | let x: () = match true {
Future breakage diagnostic:
error: this function depends on never type fallback being `()`
--> $DIR/never-type-fallback-breaking.rs:28:1
--> $DIR/never-type-fallback-breaking.rs:32:1
|
LL | fn q() -> Option<()> {
| ^^^^^^^^^^^^^^^^^^^^
@ -128,7 +128,7 @@ LL | fn q() -> Option<()> {
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:35:5
--> $DIR/never-type-fallback-breaking.rs:39:5
|
LL | deserialize()?;
| ^^^^^^^^^^^^^
@ -140,7 +140,7 @@ LL | deserialize::<()>()?;
Future breakage diagnostic:
error: this function depends on never type fallback being `()`
--> $DIR/never-type-fallback-breaking.rs:45:1
--> $DIR/never-type-fallback-breaking.rs:49:1
|
LL | fn meow() -> Result<(), ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -149,7 +149,7 @@ LL | fn meow() -> Result<(), ()> {
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `(): From<!>` will fail
--> $DIR/never-type-fallback-breaking.rs:48:5
--> $DIR/never-type-fallback-breaking.rs:52:5
|
LL | help(1)?;
| ^^^^^^^
@ -161,7 +161,7 @@ LL | help::<(), _>(1)?;
Future breakage diagnostic:
error: this function depends on never type fallback being `()`
--> $DIR/never-type-fallback-breaking.rs:57:1
--> $DIR/never-type-fallback-breaking.rs:61:1
|
LL | pub fn fallback_return() -> Result<(), ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -170,7 +170,7 @@ LL | pub fn fallback_return() -> Result<(), ()> {
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:60:19
--> $DIR/never-type-fallback-breaking.rs:64:19
|
LL | takes_apit(|| Default::default())?;
| ^^^^^^^^^^^^^^^^^^
@ -182,7 +182,7 @@ LL | takes_apit::<()>(|| Default::default())?;
Future breakage diagnostic:
error: this function depends on never type fallback being `()`
--> $DIR/never-type-fallback-breaking.rs:71:1
--> $DIR/never-type-fallback-breaking.rs:75:1
|
LL | fn fully_apit() -> Result<(), ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -191,7 +191,7 @@ LL | fn fully_apit() -> Result<(), ()> {
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:74:17
--> $DIR/never-type-fallback-breaking.rs:78:17
|
LL | takes_apit2(mk()?);
| ^^^^^

View file

@ -1,5 +1,5 @@
error[E0277]: the trait bound `!: Default` is not satisfied
--> $DIR/never-type-fallback-breaking.rs:20:17
--> $DIR/never-type-fallback-breaking.rs:24:17
|
LL | true => Default::default(),
| ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
@ -8,7 +8,7 @@ LL | true => Default::default(),
= help: you might have intended to use the type `()` here instead
error[E0277]: the trait bound `!: Default` is not satisfied
--> $DIR/never-type-fallback-breaking.rs:35:5
--> $DIR/never-type-fallback-breaking.rs:39:5
|
LL | deserialize()?;
| ^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
@ -16,13 +16,13 @@ LL | deserialize()?;
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 <https://github.com/rust-lang/rust/issues/148922> for more information)
= help: you might have intended to use the type `()` here instead
note: required by a bound in `deserialize`
--> $DIR/never-type-fallback-breaking.rs:31:23
--> $DIR/never-type-fallback-breaking.rs:35:23
|
LL | fn deserialize<T: Default>() -> Option<T> {
| ^^^^^^^ required by this bound in `deserialize`
error[E0277]: the trait bound `(): From<!>` is not satisfied
--> $DIR/never-type-fallback-breaking.rs:48:5
--> $DIR/never-type-fallback-breaking.rs:52:5
|
LL | help(1)?;
| ^^^^^^^ the trait `From<!>` is not implemented for `()`
@ -39,13 +39,13 @@ LL | help(1)?;
and 4 others
= note: required for `!` to implement `Into<()>`
note: required by a bound in `help`
--> $DIR/never-type-fallback-breaking.rs:42:20
--> $DIR/never-type-fallback-breaking.rs:46:20
|
LL | fn help<'a: 'a, T: Into<()>, U>(_: U) -> Result<T, ()> {
| ^^^^^^^^ required by this bound in `help`
error[E0277]: the trait bound `!: Default` is not satisfied
--> $DIR/never-type-fallback-breaking.rs:60:19
--> $DIR/never-type-fallback-breaking.rs:64:19
|
LL | takes_apit(|| Default::default())?;
| ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
@ -54,7 +54,7 @@ LL | takes_apit(|| Default::default())?;
= help: you might have intended to use the type `()` here instead
error[E0277]: the trait bound `!: Default` is not satisfied
--> $DIR/never-type-fallback-breaking.rs:74:17
--> $DIR/never-type-fallback-breaking.rs:78:17
|
LL | takes_apit2(mk()?);
| ----------- ^^^^^ the trait `Default` is not implemented for `!`
@ -64,7 +64,7 @@ LL | takes_apit2(mk()?);
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 <https://github.com/rust-lang/rust/issues/148922> for more information)
= help: you might have intended to use the type `()` here instead
note: required by a bound in `takes_apit2`
--> $DIR/never-type-fallback-breaking.rs:69:25
--> $DIR/never-type-fallback-breaking.rs:73:25
|
LL | fn takes_apit2(_x: impl Default) {}
| ^^^^^^^ required by this bound in `takes_apit2`

View file

@ -1,3 +1,7 @@
// This is a test for various ways in which the change to the never type
// fallback can break things and for the `dependency_on_unit_never_type_fallback`
// lint.
//
//@ revisions: e2021 e2024
//
//@[e2021] edition: 2021

View file

@ -1,26 +1,71 @@
// Test that ! errors when used in illegal positions with feature(never_type) disabled
trait Foo {
type Wub;
mod ungated {
//! Functions returning `!` directly (as in `-> !`) and function pointers doing the same are
//! allowed with no gates.
fn panic() -> ! {
panic!();
}
fn takes_fn_ptr(x: fn() -> !) -> ! {
x()
}
}
type Ma = (u32, !, i32); //~ ERROR type is experimental
type Meeshka = Vec<!>; //~ ERROR type is experimental
type Mow = &'static fn(!) -> !; //~ ERROR type is experimental
type Skwoz = &'static mut !; //~ ERROR type is experimental
mod gated {
//! All other mentions of the type are gated.
impl Foo for Meeshka {
type Wub = !; //~ ERROR type is experimental
trait Foo {
type Wub;
}
type Ma = (u32, !, i32); //~ ERROR type is experimental
type Meeshka = Vec<!>; //~ ERROR type is experimental
type Mow = &'static fn(!) -> !; //~ ERROR type is experimental
type Skwoz = &'static mut !; //~ ERROR type is experimental
type Meow = fn() -> Result<(), !>; //~ ERROR type is experimental
impl Foo for Meeshka {
type Wub = !; //~ ERROR type is experimental
}
fn look_ma_no_feature_gate<F: FnOnce() -> !>() {} //~ ERROR type is experimental
fn tadam(f: &dyn Fn() -> !) {} //~ ERROR type is experimental
fn toudoum() -> impl Fn() -> ! { //~ ERROR type is experimental
|| panic!()
}
fn infallible() -> Result<(), !> { //~ ERROR type is experimental
Ok(())
}
}
fn look_ma_no_feature_gate<F: FnOnce() -> !>() {} //~ ERROR type is experimental
fn tadam(f: &dyn Fn() -> !) {} //~ ERROR type is experimental
fn panic() -> ! {
panic!();
}
fn toudoum() -> impl Fn() -> ! { //~ ERROR type is experimental
panic
mod hack {
//! There is a hack which, by exploiting the fact that `fn() -> !` can be named stably and that
//! type system does not interact with stability, allows one to mention the never type while
//! avoiding any and all feature gates. It is generally considered a "hack"/compiler bug, and
//! thus users of this hack resign stability guarantees. However, fixing this is more trouble
//! than good.
trait F {
type Ret;
}
impl<T> F for fn() -> T {
type Ret = T;
}
type Never = <fn() -> ! as F>::Ret;
fn damn(
never: Never,
_: &dyn Fn() -> Never,
) -> (impl Fn() -> Never, &'static mut Never, Never, u8) {
(|| never, never, never, never)
}
}
fn main() {
}
fn main() {}

View file

@ -1,27 +1,17 @@
error[E0658]: the `!` type is experimental
--> $DIR/feature-gate-never_type.rs:7:17
--> $DIR/feature-gate-never_type.rs:23:21
|
LL | type Ma = (u32, !, i32);
| ^
LL | type Ma = (u32, !, i32);
| ^
|
= note: see issue #35121 <https://github.com/rust-lang/rust/issues/35121> for more information
= help: add `#![feature(never_type)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: the `!` type is experimental
--> $DIR/feature-gate-never_type.rs:8:20
--> $DIR/feature-gate-never_type.rs:24:24
|
LL | type Meeshka = Vec<!>;
| ^
|
= note: see issue #35121 <https://github.com/rust-lang/rust/issues/35121> for more information
= help: add `#![feature(never_type)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: the `!` type is experimental
--> $DIR/feature-gate-never_type.rs:9:24
|
LL | type Mow = &'static fn(!) -> !;
LL | type Meeshka = Vec<!>;
| ^
|
= note: see issue #35121 <https://github.com/rust-lang/rust/issues/35121> for more information
@ -29,55 +19,85 @@ LL | type Mow = &'static fn(!) -> !;
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: the `!` type is experimental
--> $DIR/feature-gate-never_type.rs:10:27
--> $DIR/feature-gate-never_type.rs:25:28
|
LL | type Skwoz = &'static mut !;
| ^
LL | type Mow = &'static fn(!) -> !;
| ^
|
= note: see issue #35121 <https://github.com/rust-lang/rust/issues/35121> for more information
= help: add `#![feature(never_type)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: the `!` type is experimental
--> $DIR/feature-gate-never_type.rs:13:16
--> $DIR/feature-gate-never_type.rs:26:31
|
LL | type Wub = !;
| ^
LL | type Skwoz = &'static mut !;
| ^
|
= note: see issue #35121 <https://github.com/rust-lang/rust/issues/35121> for more information
= help: add `#![feature(never_type)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: the `!` type is experimental
--> $DIR/feature-gate-never_type.rs:16:43
--> $DIR/feature-gate-never_type.rs:27:36
|
LL | fn look_ma_no_feature_gate<F: FnOnce() -> !>() {}
| ^
LL | type Meow = fn() -> Result<(), !>;
| ^
|
= note: see issue #35121 <https://github.com/rust-lang/rust/issues/35121> for more information
= help: add `#![feature(never_type)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: the `!` type is experimental
--> $DIR/feature-gate-never_type.rs:17:26
--> $DIR/feature-gate-never_type.rs:30:20
|
LL | fn tadam(f: &dyn Fn() -> !) {}
| ^
LL | type Wub = !;
| ^
|
= note: see issue #35121 <https://github.com/rust-lang/rust/issues/35121> for more information
= help: add `#![feature(never_type)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: the `!` type is experimental
--> $DIR/feature-gate-never_type.rs:21:30
--> $DIR/feature-gate-never_type.rs:33:47
|
LL | fn toudoum() -> impl Fn() -> ! {
LL | fn look_ma_no_feature_gate<F: FnOnce() -> !>() {}
| ^
|
= note: see issue #35121 <https://github.com/rust-lang/rust/issues/35121> for more information
= help: add `#![feature(never_type)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: the `!` type is experimental
--> $DIR/feature-gate-never_type.rs:35:30
|
LL | fn tadam(f: &dyn Fn() -> !) {}
| ^
|
= note: see issue #35121 <https://github.com/rust-lang/rust/issues/35121> for more information
= help: add `#![feature(never_type)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 8 previous errors
error[E0658]: the `!` type is experimental
--> $DIR/feature-gate-never_type.rs:37:34
|
LL | fn toudoum() -> impl Fn() -> ! {
| ^
|
= note: see issue #35121 <https://github.com/rust-lang/rust/issues/35121> for more information
= help: add `#![feature(never_type)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: the `!` type is experimental
--> $DIR/feature-gate-never_type.rs:41:35
|
LL | fn infallible() -> Result<(), !> {
| ^
|
= note: see issue #35121 <https://github.com/rust-lang/rust/issues/35121> for more information
= help: add `#![feature(never_type)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 10 previous errors
For more information about this error, try `rustc --explain E0658`.

View file

@ -1,7 +1,6 @@
//@ check-pass
#![warn(unused_must_use)]
#![feature(never_type)]
use std::ops::Add;
use std::ops::Sub;

View file

@ -1,5 +1,5 @@
warning: unused return value of `add` that must be used
--> $DIR/issue-103320-must-use-ops.rs:16:5
--> $DIR/issue-103320-must-use-ops.rs:15:5
|
LL | x.add(4);
| ^^^^^^^^
@ -16,7 +16,7 @@ LL | let _ = x.add(4);
| +++++++
warning: unused return value of `sub` that must be used
--> $DIR/issue-103320-must-use-ops.rs:18:5
--> $DIR/issue-103320-must-use-ops.rs:17:5
|
LL | x.sub(4);
| ^^^^^^^^
@ -28,7 +28,7 @@ LL | let _ = x.sub(4);
| +++++++
warning: unused return value of `mul` that must be used
--> $DIR/issue-103320-must-use-ops.rs:20:5
--> $DIR/issue-103320-must-use-ops.rs:19:5
|
LL | x.mul(4);
| ^^^^^^^^
@ -40,7 +40,7 @@ LL | let _ = x.mul(4);
| +++++++
warning: unused return value of `div` that must be used
--> $DIR/issue-103320-must-use-ops.rs:22:5
--> $DIR/issue-103320-must-use-ops.rs:21:5
|
LL | x.div(4);
| ^^^^^^^^
@ -52,7 +52,7 @@ LL | let _ = x.div(4);
| +++++++
warning: unused return value of `rem` that must be used
--> $DIR/issue-103320-must-use-ops.rs:24:5
--> $DIR/issue-103320-must-use-ops.rs:23:5
|
LL | x.rem(4);
| ^^^^^^^^

View file

@ -1,7 +1,6 @@
//@ check-pass
#![feature(auto_traits)]
#![feature(negative_impls)]
#![feature(never_type)]
fn main() {

View file

@ -1,9 +1,9 @@
// Test that we can use a ! for an argument of type !
//
//@ check-pass
#![feature(never_type)]
#![allow(unreachable_code)]
#![expect(unreachable_code)]
fn foo(x: !) -> ! {
x

View file

@ -1,5 +1,5 @@
// Test that we can explicitly cast ! to another type
//
//@ check-pass
#![feature(never_type)]

View file

@ -0,0 +1,18 @@
Future incompatibility report: Future breakage diagnostic:
warning: this function depends on never type fallback being `()`
--> $DIR/defaulted-never-note.rs:38:1
|
LL | fn main() {
| ^^^^^^^^^
|
= help: specify the types explicitly
note: in edition 2024, the requirement `!: OnlyUnit` will fail
--> $DIR/defaulted-never-note.rs:40:19
|
LL | requires_unit(x);
| ^
help: use `()` annotations to avoid fallback changes
|
LL | let x: () = return;
| ++++

View file

@ -0,0 +1,62 @@
error[E0277]: the trait bound `!: OnlyUnit` is not satisfied
--> $DIR/defaulted-never-note.rs:40:19
|
LL | requires_unit(x);
| ------------- ^ the trait `OnlyUnit` is not implemented for `!`
| |
| required by a bound introduced by this call
|
help: the trait `OnlyUnit` is implemented for `()`
--> $DIR/defaulted-never-note.rs:13:1
|
LL | impl OnlyUnit for () {}
| ^^^^^^^^^^^^^^^^^^^^
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 <https://github.com/rust-lang/rust/issues/148922> for more information)
= help: you might have intended to use the type `()` here instead
note: required by a bound in `requires_unit`
--> $DIR/defaulted-never-note.rs:16:26
|
LL | fn requires_unit(_: impl OnlyUnit) {}
| ^^^^^^^^ required by this bound in `requires_unit`
error[E0277]: the trait bound `!: OnlyU32` is not satisfied
--> $DIR/defaulted-never-note.rs:48:18
|
LL | requires_u32(x);
| ------------ ^ the trait `OnlyU32` is not implemented for `!`
| |
| required by a bound introduced by this call
|
help: the trait `OnlyU32` is implemented for `u32`
--> $DIR/defaulted-never-note.rs:23:1
|
LL | impl OnlyU32 for u32 {}
| ^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `requires_u32`
--> $DIR/defaulted-never-note.rs:26:25
|
LL | fn requires_u32(_: impl OnlyU32) {}
| ^^^^^^^ required by this bound in `requires_u32`
error[E0277]: the trait bound `!: Nothing` is not satisfied
--> $DIR/defaulted-never-note.rs:54:22
|
LL | requires_nothing(x);
| ---------------- ^ the trait `Nothing` is not implemented for `!`
| |
| required by a bound introduced by this call
|
help: this trait has no implementations, consider adding one
--> $DIR/defaulted-never-note.rs:31:1
|
LL | trait Nothing {}
| ^^^^^^^^^^^^^
note: required by a bound in `requires_nothing`
--> $DIR/defaulted-never-note.rs:34:29
|
LL | fn requires_nothing(_: impl Nothing) {}
| ^^^^^^^ required by this bound in `requires_nothing`
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`.

View file

@ -1,24 +0,0 @@
error[E0277]: the trait bound `!: ImplementedForUnitButNotNever` is not satisfied
--> $DIR/defaulted-never-note.rs:27:9
|
LL | foo(_x);
| --- ^^ the trait `ImplementedForUnitButNotNever` is not implemented for `!`
| |
| required by a bound introduced by this call
|
help: the trait `ImplementedForUnitButNotNever` is implemented for `()`
--> $DIR/defaulted-never-note.rs:20:1
|
LL | impl ImplementedForUnitButNotNever for () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 <https://github.com/rust-lang/rust/issues/148922> for more information)
= help: you might have intended to use the type `()` here instead
note: required by a bound in `foo`
--> $DIR/defaulted-never-note.rs:22:11
|
LL | fn foo<T: ImplementedForUnitButNotNever>(_t: T) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -1,18 +0,0 @@
Future incompatibility report: Future breakage diagnostic:
warning: this function depends on never type fallback being `()`
--> $DIR/defaulted-never-note.rs:25:1
|
LL | fn smeg() {
| ^^^^^^^^^
|
= help: specify the types explicitly
note: in edition 2024, the requirement `!: ImplementedForUnitButNotNever` will fail
--> $DIR/defaulted-never-note.rs:27:9
|
LL | foo(_x);
| ^^
help: use `()` annotations to avoid fallback changes
|
LL | let _x: () = return;
| ++++

View file

@ -1,37 +1,58 @@
//@ revisions: nofallback fallback
//@[fallback] edition: 2024
//@[nofallback] run-pass
//@[fallback] check-fail
// Test diagnostic for the case where a trait is not implemented for `!`. If it is implemented
// for `()`, we want to add a note saying that this might be caused by a breaking change in the
// compiler.
//
//@ revisions: e2021 e2024
//@[e2021] edition: 2021
//@[e2024] edition: 2024
//@[e2021] run-pass
#![expect(dependency_on_unit_never_type_fallback, unused)]
trait Deserialize: Sized {
fn deserialize() -> Result<Self, String>;
}
trait OnlyUnit {}
impl Deserialize for () {
fn deserialize() -> Result<(), String> {
Ok(())
}
}
impl OnlyUnit for () {}
//[e2024]~^ help: trait `OnlyUnit` is implemented for `()`
trait ImplementedForUnitButNotNever {}
fn requires_unit(_: impl OnlyUnit) {}
//[e2024]~^ note: required by this bound in `requires_unit`
//[e2024]~| note: required by a bound in `requires_unit`
impl ImplementedForUnitButNotNever for () {} //[fallback]~ HELP trait `ImplementedForUnitButNotNever` is implemented for `()`
fn foo<T: ImplementedForUnitButNotNever>(_t: T) {}
//[fallback]~^ note: required by this bound in `foo`
//[fallback]~| note: required by a bound in `foo`
fn smeg() {
let _x = return;
foo(_x);
//[fallback]~^ ERROR the trait bound
//[fallback]~| NOTE the trait `ImplementedForUnitButNotNever` is not implemented
//[fallback]~| NOTE this error might have been caused
//[fallback]~| NOTE required by a bound introduced by this call
//[fallback]~| HELP you might have intended to use the type `()`
}
trait OnlyU32 {}
impl OnlyU32 for u32 {}
//[e2024]~^ help: the trait `OnlyU32` is implemented for `u32`
fn requires_u32(_: impl OnlyU32) {}
//[e2024]~^ note: required by this bound in `requires_u32`
//[e2024]~| note: required by a bound in `requires_u32`
trait Nothing {}
//[e2024]~^ help: this trait has no implementations, consider adding one
fn requires_nothing(_: impl Nothing) {}
//[e2024]~^ note: required by this bound in `requires_nothing`
//[e2024]~| note: required by a bound in `requires_nothing`
fn main() {
smeg();
let x = return;
requires_unit(x);
//[e2024]~^ error: the trait bound `!: OnlyUnit` is not satisfied
//[e2024]~| note: the trait `OnlyUnit` is not implemented for `!`
//[e2024]~| note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 <https://github.com/rust-lang/rust/issues/148922> for more information)
//[e2024]~| note: required by a bound introduced by this call
//[e2024]~| help: you might have intended to use the type `()`
#[cfg(e2024)]
requires_u32(x);
//[e2024]~^ error: the trait bound `!: OnlyU32` is not satisfied
//[e2024]~| note: the trait `OnlyU32` is not implemented for `!`
//[e2024]~| note: required by a bound introduced by this call
#[cfg(e2024)]
requires_nothing(x);
//[e2024]~^ error: the trait bound `!: Nothing` is not satisfied
//[e2024]~| note: the trait `Nothing` is not implemented for `!`
//[e2024]~| note: required by a bound introduced by this call
}

View file

@ -1,26 +0,0 @@
error[E0277]: the trait bound `!: Test` is not satisfied
--> $DIR/diverging-fallback-no-leak.rs:18:23
|
LL | unconstrained_arg(return);
| ----------------- ^^^^^^ the trait `Test` is not implemented for `!`
| |
| required by a bound introduced by this call
|
help: the following other types implement trait `Test`
--> $DIR/diverging-fallback-no-leak.rs:10:1
|
LL | impl Test for i32 {}
| ^^^^^^^^^^^^^^^^^ `i32`
LL | impl Test for () {}
| ^^^^^^^^^^^^^^^^ `()`
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 <https://github.com/rust-lang/rust/issues/148922> for more information)
= help: you might have intended to use the type `()` here instead
note: required by a bound in `unconstrained_arg`
--> $DIR/diverging-fallback-no-leak.rs:13:25
|
LL | fn unconstrained_arg<T: Test>(_: T) {}
| ^^^^ required by this bound in `unconstrained_arg`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -1,18 +0,0 @@
Future incompatibility report: Future breakage diagnostic:
warning: this function depends on never type fallback being `()`
--> $DIR/diverging-fallback-no-leak.rs:15:1
|
LL | fn main() {
| ^^^^^^^^^
|
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Test` will fail
--> $DIR/diverging-fallback-no-leak.rs:18:23
|
LL | unconstrained_arg(return);
| ^^^^^^
help: use `()` annotations to avoid fallback changes
|
LL | unconstrained_arg::<()>(return);
| ++++++

View file

@ -1,20 +0,0 @@
//@ revisions: nofallback fallback
//@[fallback] edition: 2024
//@[nofallback] check-pass
#![cfg_attr(nofallback, expect(dependency_on_unit_never_type_fallback))]
fn make_unit() {}
trait Test {}
impl Test for i32 {}
impl Test for () {}
fn unconstrained_arg<T: Test>(_: T) {}
fn main() {
// Here the type variable falls back to `!`,
// and hence we get a type error.
unconstrained_arg(return);
//[fallback]~^ error: trait bound `!: Test` is not satisfied
}

View file

@ -0,0 +1,43 @@
error: this function depends on never type fallback being `()`
--> $DIR/diverging-fallback-unconstrained-return.rs:26:1
|
LL | fn main() {
| ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: UnitReturn` will fail
--> $DIR/diverging-fallback-unconstrained-return.rs:37:23
|
LL | let _ = if true { unconstrained_return() } else { panic!() };
| ^^^^^^^^^^^^^^^^^^^^^^
= note: `#[deny(dependency_on_unit_never_type_fallback)]` (part of `#[deny(rust_2024_compatibility)]`) on by default
help: use `()` annotations to avoid fallback changes
|
LL | let _: () = if true { unconstrained_return() } else { panic!() };
| ++++
error: aborting due to 1 previous error
Future incompatibility report: Future breakage diagnostic:
error: this function depends on never type fallback being `()`
--> $DIR/diverging-fallback-unconstrained-return.rs:26:1
|
LL | fn main() {
| ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: UnitReturn` will fail
--> $DIR/diverging-fallback-unconstrained-return.rs:37:23
|
LL | let _ = if true { unconstrained_return() } else { panic!() };
| ^^^^^^^^^^^^^^^^^^^^^^
= note: `#[deny(dependency_on_unit_never_type_fallback)]` (part of `#[deny(rust_2024_compatibility)]`) on by default
help: use `()` annotations to avoid fallback changes
|
LL | let _: () = if true { unconstrained_return() } else { panic!() };
| ++++

View file

@ -0,0 +1,24 @@
error[E0277]: the trait bound `!: UnitReturn` is not satisfied
--> $DIR/diverging-fallback-unconstrained-return.rs:37:23
|
LL | let _ = if true { unconstrained_return() } else { panic!() };
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `UnitReturn` is not implemented for `!`
|
help: the following other types implement trait `UnitReturn`
--> $DIR/diverging-fallback-unconstrained-return.rs:15:1
|
LL | impl UnitReturn for i32 {}
| ^^^^^^^^^^^^^^^^^^^^^^^ `i32`
LL | impl UnitReturn for () {}
| ^^^^^^^^^^^^^^^^^^^^^^ `()`
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 <https://github.com/rust-lang/rust/issues/148922> for more information)
= help: you might have intended to use the type `()` here instead
note: required by a bound in `unconstrained_return`
--> $DIR/diverging-fallback-unconstrained-return.rs:18:28
|
LL | fn unconstrained_return<T: UnitReturn>() -> T {
| ^^^^^^^^^^ required by this bound in `unconstrained_return`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -4,8 +4,8 @@
// in the objc crate, where changing the fallback from `!` to `()`
// resulted in unsoundness.
//
//@ revisions: nofallback fallback
//@[fallback] edition: 2024
//@ revisions: e2021 e2024
//@[e2024] edition: 2024
#![expect(unit_bindings)]
@ -24,8 +24,8 @@ fn unconstrained_return<T: UnitReturn>() -> T {
}
fn main() {
//[nofallback]~^ error: this function depends on never type fallback being `()`
//[nofallback]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
//[e2021]~^ error: this function depends on never type fallback being `()`
//[e2021]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
// In Ye Olde Days, the `T` parameter of `unconstrained_return`
// winds up "entangled" with the `!` type that results from
@ -34,5 +34,5 @@ fn main() {
// idea was to change that fallback to `!`, but that would have resulted
// in this code no longer compiling (or worse, in some cases it injected
// unsound results).
let _ = if true { unconstrained_return() } else { panic!() }; //[fallback]~ error: the trait bound `!: UnitReturn` is not satisfied
let _ = if true { unconstrained_return() } else { panic!() }; //[e2024]~ error: the trait bound `!: UnitReturn` is not satisfied
}

View file

@ -1,10 +1,9 @@
//@ check-pass
// Regression test for <https://github.com/rust-lang/rust/issues/120600>
//
// issue: rust-lang/rust#120600
//@ edition: 2024
//@ check-pass
#![allow(internal_features)]
#![feature(never_type, rustc_attrs)]
#![rustc_never_type_options(fallback = "never")]
#![feature(never_type)]
fn ice(a: !) {
a == a;

View file

@ -1,6 +1,9 @@
// Check that we don't consider types which aren't publicly uninhabited as
// uninhabited for purposes of pattern matching.
//
//@ check-fail
#![feature(exhaustive_patterns, never_type)]
#![feature(never_type)]
mod inner {
pub struct Wrapper<T>(T);

View file

@ -1,5 +1,5 @@
error[E0005]: refutable pattern in local binding
--> $DIR/exhaustive_patterns.rs:21:9
--> $DIR/exhaustive_patterns.rs:24:9
|
LL | let Either::A(()) = foo();
| ^^^^^^^^^^^^^ pattern `Either::B(_)` not covered
@ -7,7 +7,7 @@ LL | let Either::A(()) = foo();
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
note: `Either<(), !>` defined here
--> $DIR/exhaustive_patterns.rs:9:6
--> $DIR/exhaustive_patterns.rs:12:6
|
LL | enum Either<A, B> {
| ^^^^^^

View file

@ -0,0 +1,18 @@
Future incompatibility report: Future breakage diagnostic:
warning: this function depends on never type fallback being `()`
--> $DIR/fallback-closure-ret.rs:21:1
|
LL | fn main() {
| ^^^^^^^^^
|
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Bar` will fail
--> $DIR/fallback-closure-ret.rs:22:5
|
LL | foo(|| panic!());
| ^^^^^^^^^^^^^^^^
help: use `()` annotations to avoid fallback changes
|
LL | foo::<()>(|| panic!());
| ++++++

View file

@ -0,0 +1,24 @@
error[E0277]: the trait bound `!: Bar` is not satisfied
--> $DIR/fallback-closure-ret.rs:22:5
|
LL | foo(|| panic!());
| ^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `!`
|
help: the following other types implement trait `Bar`
--> $DIR/fallback-closure-ret.rs:15:1
|
LL | impl Bar for () {}
| ^^^^^^^^^^^^^^^ `()`
LL | impl Bar for u32 {}
| ^^^^^^^^^^^^^^^^ `u32`
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 <https://github.com/rust-lang/rust/issues/148922> for more information)
= help: you might have intended to use the type `()` here instead
note: required by a bound in `foo`
--> $DIR/fallback-closure-ret.rs:18:11
|
LL | fn foo<R: Bar>(_: impl Fn() -> R) {}
| ^^^ required by this bound in `foo`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -1,12 +1,15 @@
// Tests the pattern of returning `!` from a closure and then checking if the
// return type iumplements a trait (not implemented for `!`).
//
// This test used to test that this pattern is not broken by context dependant
// never type fallback. However, it got removed, so now this is an example of
// expected breakage from the never type fallback change.
//
//@ revisions: nofallback fallback
//@[nofallback] check-pass
//@[fallback] edition: 2024
#![cfg_attr(nofallback, expect(dependency_on_unit_never_type_fallback))]
//@ revisions: e2021 e2024
//@[e2021] edition: 2021
//@[e2024] edition: 2024
//
//@[e2021] check-pass
trait Bar {}
impl Bar for () {}
@ -14,6 +17,7 @@ impl Bar for u32 {}
fn foo<R: Bar>(_: impl Fn() -> R) {}
#[cfg_attr(e2021, expect(dependency_on_unit_never_type_fallback))]
fn main() {
foo(|| panic!()); //[fallback]~ error: the trait bound `!: Bar` is not satisfied
foo(|| panic!()); //[e2024]~ error: the trait bound `!: Bar` is not satisfied
}

View file

@ -0,0 +1,15 @@
error[E0271]: expected `{closure@fallback-closure-wrap.rs:16:40}` to return `()`, but it returns `!`
--> $DIR/fallback-closure-wrap.rs:17:9
|
LL | let error = Closure::wrap(Box::new(move || {
| ------- this closure
LL | panic!("Can't connect to server.");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `!`
|
= note: expected unit type `()`
found type `!`
= note: required for the cast from `Box<{closure@$DIR/fallback-closure-wrap.rs:16:40: 16:47}>` to `Box<dyn FnMut()>`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0271`.

View file

@ -1,22 +1,21 @@
// This is a minified example from Crater breakage observed when attempting to
// stabilize never type, nstoddard/webgl-gui @ 22f0169f.
//
// This particular test case currently fails as the inference to `()` rather
// than `!` happens as a result of an `as` cast, which is not currently tracked.
// Crater did not find many cases of this occurring, but it is included for
// awareness.
//
//@ revisions: nofallback fallback
//@[fallback] edition: 2024
//@[nofallback] check-pass
//@[fallback] check-fail
//@ revisions: e2021 e2024
//@[e2021] edition: 2021
//@[e2024] edition: 2024
//
//@[e2021] check-pass
use std::marker::PhantomData;
fn main() {
let error = Closure::wrap(Box::new(move || {
panic!("Can't connect to server.");
//[fallback]~^ ERROR to return `()`, but it returns `!`
//[e2024]~^ ERROR to return `()`, but it returns `!`
}) as Box<dyn FnMut()>);
}

View file

@ -1,8 +1,10 @@
// Test that we can call static methods on ! both directly and when it appears in a generic
//
//@ run-pass
//@ check-run-results
#![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;

View file

@ -0,0 +1,2 @@
! is !
None is none

View file

@ -1,11 +0,0 @@
//@ check-pass
#![expect(dependency_on_unit_never_type_fallback)]
fn main() {}
trait T {}
impl T for () {}
fn should_ret_unit() -> impl T {
panic!()
}

View file

@ -1,14 +0,0 @@
Future incompatibility report: Future breakage diagnostic:
warning: this function depends on never type fallback being `()`
--> $DIR/impl_trait_fallback.rs:9:1
|
LL | fn should_ret_unit() -> impl T {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: specify the types explicitly
note: in edition 2024, the requirement `!: T` will fail
--> $DIR/impl_trait_fallback.rs:9:25
|
LL | fn should_ret_unit() -> impl T {
| ^^^^^^

View file

@ -1,25 +0,0 @@
//@ edition:2015..2021
#![feature(type_alias_impl_trait)]
fn main() {}
trait T {}
impl T for i32 {}
fn should_ret_unit() -> impl T {
//~^ ERROR `(): T` is not satisfied
panic!()
}
type Foo = impl T;
#[define_opaque(Foo)]
fn a() -> Foo {
//~^ ERROR `(): T` is not satisfied
panic!()
}
#[define_opaque(Foo)]
fn b() -> Foo {
42
}

View file

@ -1,33 +0,0 @@
error[E0277]: the trait bound `(): T` is not satisfied
--> $DIR/impl_trait_fallback2.rs:9:25
|
LL | fn should_ret_unit() -> impl T {
| ^^^^^^ the trait `T` is not implemented for `()`
LL |
LL | panic!()
| -------- return type was inferred to be `_` here
|
help: the trait `T` is implemented for `i32`
--> $DIR/impl_trait_fallback2.rs:7:1
|
LL | impl T for i32 {}
| ^^^^^^^^^^^^^^
error[E0277]: the trait bound `(): T` is not satisfied
--> $DIR/impl_trait_fallback2.rs:17:11
|
LL | fn a() -> Foo {
| ^^^ the trait `T` is not implemented for `()`
LL |
LL | panic!()
| -------- return type was inferred to be `_` here
|
help: the trait `T` is implemented for `i32`
--> $DIR/impl_trait_fallback2.rs:7:1
|
LL | impl T for i32 {}
| ^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.

View file

@ -1,17 +0,0 @@
//@ edition:2015..2021
#![feature(type_alias_impl_trait)]
fn main() {}
trait T {
type Assoc;
}
type Foo = impl T;
#[define_opaque(Foo)]
fn a() -> Foo {
//~^ ERROR the trait bound `(): T` is not satisfied
// This is not a defining use, it doesn't actually constrain the opaque type.
panic!()
}

View file

@ -1,18 +0,0 @@
error[E0277]: the trait bound `(): T` is not satisfied
--> $DIR/impl_trait_fallback3.rs:13:11
|
LL | fn a() -> Foo {
| ^^^ the trait `T` is not implemented for `()`
...
LL | panic!()
| -------- return type was inferred to be `_` here
|
help: this trait has no implementations, consider adding one
--> $DIR/impl_trait_fallback3.rs:6:1
|
LL | trait T {
| ^^^^^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -1,26 +0,0 @@
//@ edition:2015..2021
#![feature(type_alias_impl_trait)]
trait T {
type Assoc: Cake;
}
trait Cake: std::fmt::Display {
fn cake() -> Self;
}
type Foo = impl T;
fn foo() -> impl T {
//~^ ERROR `(): T` is not satisfied
panic!()
}
#[define_opaque(Foo)]
fn a() -> Foo {
foo()
}
fn main() {
println!("{}", <Foo as T>::Assoc::cake());
}

View file

@ -1,18 +0,0 @@
error[E0277]: the trait bound `(): T` is not satisfied
--> $DIR/impl_trait_fallback4.rs:14:13
|
LL | fn foo() -> impl T {
| ^^^^^^ the trait `T` is not implemented for `()`
LL |
LL | panic!()
| -------- return type was inferred to be `_` here
|
help: this trait has no implementations, consider adding one
--> $DIR/impl_trait_fallback4.rs:4:1
|
LL | trait T {
| ^^^^^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -1,13 +1,14 @@
// Regression test for <https://github.com/rust-lang/rust/issues/44402>
//
// Previously inhabitedness check was handling cycles incorrectly causing this
// to not compile.
//
//@ 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>,
@ -30,4 +31,4 @@ fn test_b() {
}
}
fn main() { }
fn main() {}

View file

@ -1,3 +1,5 @@
// Regression test for <https://github.com/rust-lang/rust/issues/51506>
#![feature(never_type, specialization)]
#![allow(incomplete_features)]

View file

@ -1,12 +1,12 @@
error[E0277]: `!` is not an iterator
--> $DIR/issue-51506.rs:13:24
--> $DIR/issue-51506.rs:15:24
|
LL | default type Out = !;
| ^ `!` is not an iterator
|
= help: the trait `Iterator` is not implemented for `!`
note: required by a bound in `Trait::Out`
--> $DIR/issue-51506.rs:7:15
--> $DIR/issue-51506.rs:9:15
|
LL | type Out: Iterator<Item = u32>;
| ^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait::Out`

View file

@ -1,9 +1,9 @@
// Test that an assignment of type ! makes the rest of the block dead code.
//
//@ check-pass
#![feature(never_type)]
#![allow(dropping_copy_types)]
#![expect(dropping_copy_types)]
#![warn(unused)]
fn main() {

View file

@ -1,7 +1,6 @@
// Test that we can't use another type in place of !
#![feature(never_type)]
#![deny(warnings)]
fn main() {
let x: ! = "hello"; //~ ERROR mismatched types

View file

@ -1,5 +1,5 @@
error[E0308]: mismatched types
--> $DIR/never-assign-wrong-type.rs:7:16
--> $DIR/never-assign-wrong-type.rs:6:16
|
LL | let x: ! = "hello";
| - ^^^^^^^ expected `!`, found `&str`

View file

@ -1,5 +1,5 @@
// Test that we can use ! as an associated type.
//
//@ check-pass
#![feature(never_type)]

View file

@ -1,5 +1,5 @@
// Regression test for <https://github.com/rust-lang/rust/issues/133947>.
//
// Make sure we don't ICE when there's `!` in a range pattern.
//
// This shouldn't be allowed anyways, but we only deny it during MIR

View file

@ -1,10 +1,11 @@
// Test that `!` can be coerced to multiple different types after getting it
// from pattern matching.
//
//@ run-pass
#![allow(unused_variables)]
#![allow(unreachable_code)]
#![allow(unreachable_patterns)]
// Test that we can extract a ! through pattern matching then use it as several different types.
#![feature(never_type)]
#![expect(unused_variables)]
#![expect(unreachable_code)]
fn main() {
let x: Result<u32, !> = Ok(123);

View file

@ -1,5 +1,5 @@
// Test that we can use ! as an argument to a trait impl.
//
//@ check-pass
#![feature(never_type)]

View file

@ -1,3 +1,5 @@
// Check that the never type can be used in various positions.
//
//@ run-pass
#![feature(never_type)]

View file

@ -1,17 +0,0 @@
error[E0277]: the trait bound `E: From<()>` is not satisfied
--> $DIR/never-value-fallback-issue-66757.rs:27:6
|
LL | <E as From<_>>::from(never);
| ^ unsatisfied trait bound
|
help: the trait `From<()>` is not implemented for `E`
but trait `From<!>` is implemented for it
--> $DIR/never-value-fallback-issue-66757.rs:16:1
|
LL | impl From<!> for E {
| ^^^^^^^^^^^^^^^^^^
= help: for that trait implementation, expected `!`, found `()`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -1,30 +0,0 @@
// Regression test for #66757
//
// Test than when you have a `!` value (e.g., the local variable
// never) and an uninferred variable (here the argument to `From`) it
// doesn't fallback to `()` but rather `!`.
//
//@ revisions: nofallback fallback
//@[fallback] edition: 2024
//@[fallback] run-pass
//@[nofallback] check-fail
#![feature(never_type)]
struct E;
impl From<!> for E {
fn from(_: !) -> E {
E
}
}
#[allow(unreachable_code)]
#[allow(dead_code)]
#[allow(unused_must_use)]
fn foo(never: !) {
<E as From<!>>::from(never); // Ok
<E as From<_>>::from(never); //[nofallback]~ ERROR trait bound `E: From<()>` is not satisfied
}
fn main() { }

View file

@ -1,11 +1,9 @@
//@ check-pass
#![crate_type="lib"]
#![feature(never_type)]
#![allow(dead_code)]
#![allow(unreachable_code)]
#![allow(unused_variables)]
#![expect(unreachable_code)]
#![expect(unused_variables)]
struct Foo;
@ -21,3 +19,5 @@ pub fn ub() {
};
f(x)
}
fn main() {}

View file

@ -1,4 +1,4 @@
// issue: rust-lang/rust#66757
// Regression test for <https://github.com/rust-lang/rust/issues/66757>.
//
// See also: `tests/ui/never_type/from_infer_breaking_with_unit_fallback.rs`.
//

View file

@ -1,3 +1,5 @@
// Regression test for <https://github.com/rust-lang/rust/issues/121445>
#![feature(never_type)]
fn test2() {

View file

@ -1,5 +1,5 @@
error[E0369]: no implementation for `SingleVariant | ()`
--> $DIR/span-bug-issue-121445.rs:6:9
--> $DIR/span-bug-issue-121445.rs:8:9
|
LL | let c2 = SingleVariant::Points(0)
| ------------------------ SingleVariant
@ -10,7 +10,7 @@ LL | | };
| |_________- ()
|
note: an implementation of `BitOr<()>` might be missing for `SingleVariant`
--> $DIR/span-bug-issue-121445.rs:11:1
--> $DIR/span-bug-issue-121445.rs:13:1
|
LL | enum SingleVariant {
| ^^^^^^^^^^^^^^^^^^ must implement `BitOr<()>`

View file

@ -8,7 +8,6 @@
//@ ignore-backends: gcc
#![feature(rustc_private)]
#![feature(never_type)]
#![feature(panic_always_abort)]
#![allow(invalid_from_utf8)]