Add some more tests for the never type fallback

This commit is contained in:
Maybe Waffle 2024-04-11 17:29:36 +00:00 committed by Waffle Lapkin
parent 3b3e504235
commit 0f63cd1056
5 changed files with 147 additions and 0 deletions

View File

@ -0,0 +1,26 @@
error[E0277]: the trait bound `!: Default` is not satisfied
--> $DIR/never-type-fallback-breaking.rs:17:17
|
LL | true => Default::default(),
| ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
|
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
= help: did you intend to use the type `()` here instead?
error[E0277]: the trait bound `!: Default` is not satisfied
--> $DIR/never-type-fallback-breaking.rs:30:5
|
LL | deserialize()?;
| ^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
|
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
= help: did you intend to use the type `()` here instead?
note: required by a bound in `deserialize`
--> $DIR/never-type-fallback-breaking.rs:26:23
|
LL | fn deserialize<T: Default>() -> Option<T> {
| ^^^^^^^ required by this bound in `deserialize`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -0,0 +1,34 @@
//@ revisions: e2021 e2024
//
//@[e2021] edition: 2021
//@[e2024] edition: 2024
//@[e2024] compile-flags: -Zunstable-options
//
//@[e2021] run-pass
//@[e2024] check-fail
fn main() {
m();
q();
}
fn m() {
let x = match true {
true => Default::default(),
//[e2024]~^ error: the trait bound `!: Default` is not satisfied
false => panic!("..."),
};
dbg!(x);
}
fn q() -> Option<()> {
fn deserialize<T: Default>() -> Option<T> {
Some(T::default())
}
deserialize()?;
//[e2024]~^ error: the trait bound `!: Default` is not satisfied
None
}

View File

@ -0,0 +1,29 @@
// issue: rust-lang/rust#66757
//
// This is a *minimization* of the issue.
// Note that the original version with the `?` does not fail anymore even with fallback to unit,
// see `tests/ui/never_type/question_mark_from_never.rs`.
//
//@ revisions: unit never
//@[never] check-pass
#![allow(internal_features)]
#![feature(rustc_attrs, never_type)]
#![cfg_attr(unit, rustc_never_type_options(fallback = "unit"))]
#![cfg_attr(never, rustc_never_type_options(fallback = "never"))]
struct E;
impl From<!> for E {
fn from(_: !) -> E {
E
}
}
#[allow(unreachable_code)]
fn foo(never: !) {
<E as From<!>>::from(never); // Ok
<E as From<_>>::from(never); // Should the inference fail?
//[unit]~^ error: the trait bound `E: From<()>` is not satisfied
}
fn main() {}

View File

@ -0,0 +1,12 @@
error[E0277]: the trait bound `E: From<()>` is not satisfied
--> $DIR/from_infer_breaking_with_unit_fallback.rs:25:6
|
LL | <E as From<_>>::from(never); // Should the inference fail?
| ^ the trait `From<()>` is not implemented for `E`
|
= help: the trait `From<!>` is implemented 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

@ -0,0 +1,46 @@
// issue: rust-lang/rust#66757
//
// See also: `tests/ui/never_type/from_infer_breaking_with_unit_fallback.rs`.
//
//@ revisions: unit never
//@ check-pass
#![allow(internal_features)]
#![feature(rustc_attrs, never_type)]
#![cfg_attr(unit, rustc_never_type_options(fallback = "unit"))]
#![cfg_attr(never, rustc_never_type_options(fallback = "never"))]
type Infallible = !;
struct E;
impl From<Infallible> for E {
fn from(_: Infallible) -> E {
E
}
}
fn u32_try_from(x: u32) -> Result<u32, Infallible> {
Ok(x)
}
fn _f() -> Result<(), E> {
// In an old attempt to make `Infallible = !` this caused a problem.
//
// Because at the time the code desugared to
//
// match u32::try_from(1u32) {
// Ok(x) => x, Err(e) => return Err(E::from(e))
// }
//
// With `Infallible = !`, `e: !` but with fallback to `()`, `e` in `E::from(e)` decayed to `()`
// causing an error.
//
// This does not happen with `Infallible = !`.
// And also does not happen with the newer `?` desugaring that does not pass `e` by value.
// (instead we only pass `Result<!, Error>` (where `Error = !` in this case) which does not get
// the implicit coercion and thus does not decay even with fallback to unit)
u32_try_from(1u32)?;
Ok(())
}
fn main() {}