diff options
5 files changed, 147 insertions, 0 deletions
diff --git a/tests/ui/editions/never-type-fallback-breaking.e2024.stderr b/tests/ui/editions/never-type-fallback-breaking.e2024.stderr new file mode 100644 index 00000000000..e9a8882eb6c --- /dev/null +++ b/tests/ui/editions/never-type-fallback-breaking.e2024.stderr @@ -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`. diff --git a/tests/ui/editions/never-type-fallback-breaking.rs b/tests/ui/editions/never-type-fallback-breaking.rs new file mode 100644 index 00000000000..7dfa4702807 --- /dev/null +++ b/tests/ui/editions/never-type-fallback-breaking.rs @@ -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 +} diff --git a/tests/ui/never_type/from_infer_breaking_with_unit_fallback.rs b/tests/ui/never_type/from_infer_breaking_with_unit_fallback.rs new file mode 100644 index 00000000000..19a1f9d0e13 --- /dev/null +++ b/tests/ui/never_type/from_infer_breaking_with_unit_fallback.rs @@ -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() {} diff --git a/tests/ui/never_type/from_infer_breaking_with_unit_fallback.unit.stderr b/tests/ui/never_type/from_infer_breaking_with_unit_fallback.unit.stderr new file mode 100644 index 00000000000..3b8913ccf45 --- /dev/null +++ b/tests/ui/never_type/from_infer_breaking_with_unit_fallback.unit.stderr @@ -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`. diff --git a/tests/ui/never_type/question_mark_from_never.rs b/tests/ui/never_type/question_mark_from_never.rs new file mode 100644 index 00000000000..06d2a1926ea --- /dev/null +++ b/tests/ui/never_type/question_mark_from_never.rs @@ -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() {} |
