Skip to content

Commit 0f63cd1

Browse files
committed
Add some more tests for the never type fallback
1 parent 3b3e504 commit 0f63cd1

5 files changed

+147
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
error[E0277]: the trait bound `!: Default` is not satisfied
2+
--> $DIR/never-type-fallback-breaking.rs:17:17
3+
|
4+
LL | true => Default::default(),
5+
| ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
6+
|
7+
= 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)
8+
= help: did you intend to use the type `()` here instead?
9+
10+
error[E0277]: the trait bound `!: Default` is not satisfied
11+
--> $DIR/never-type-fallback-breaking.rs:30:5
12+
|
13+
LL | deserialize()?;
14+
| ^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
15+
|
16+
= 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)
17+
= help: did you intend to use the type `()` here instead?
18+
note: required by a bound in `deserialize`
19+
--> $DIR/never-type-fallback-breaking.rs:26:23
20+
|
21+
LL | fn deserialize<T: Default>() -> Option<T> {
22+
| ^^^^^^^ required by this bound in `deserialize`
23+
24+
error: aborting due to 2 previous errors
25+
26+
For more information about this error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//@ revisions: e2021 e2024
2+
//
3+
//@[e2021] edition: 2021
4+
//@[e2024] edition: 2024
5+
//@[e2024] compile-flags: -Zunstable-options
6+
//
7+
//@[e2021] run-pass
8+
//@[e2024] check-fail
9+
10+
fn main() {
11+
m();
12+
q();
13+
}
14+
15+
fn m() {
16+
let x = match true {
17+
true => Default::default(),
18+
//[e2024]~^ error: the trait bound `!: Default` is not satisfied
19+
false => panic!("..."),
20+
};
21+
22+
dbg!(x);
23+
}
24+
25+
fn q() -> Option<()> {
26+
fn deserialize<T: Default>() -> Option<T> {
27+
Some(T::default())
28+
}
29+
30+
deserialize()?;
31+
//[e2024]~^ error: the trait bound `!: Default` is not satisfied
32+
33+
None
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// issue: rust-lang/rust#66757
2+
//
3+
// This is a *minimization* of the issue.
4+
// Note that the original version with the `?` does not fail anymore even with fallback to unit,
5+
// see `tests/ui/never_type/question_mark_from_never.rs`.
6+
//
7+
//@ revisions: unit never
8+
//@[never] check-pass
9+
#![allow(internal_features)]
10+
#![feature(rustc_attrs, never_type)]
11+
#![cfg_attr(unit, rustc_never_type_options(fallback = "unit"))]
12+
#![cfg_attr(never, rustc_never_type_options(fallback = "never"))]
13+
14+
struct E;
15+
16+
impl From<!> for E {
17+
fn from(_: !) -> E {
18+
E
19+
}
20+
}
21+
22+
#[allow(unreachable_code)]
23+
fn foo(never: !) {
24+
<E as From<!>>::from(never); // Ok
25+
<E as From<_>>::from(never); // Should the inference fail?
26+
//[unit]~^ error: the trait bound `E: From<()>` is not satisfied
27+
}
28+
29+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0277]: the trait bound `E: From<()>` is not satisfied
2+
--> $DIR/from_infer_breaking_with_unit_fallback.rs:25:6
3+
|
4+
LL | <E as From<_>>::from(never); // Should the inference fail?
5+
| ^ the trait `From<()>` is not implemented for `E`
6+
|
7+
= help: the trait `From<!>` is implemented for `E`
8+
= help: for that trait implementation, expected `!`, found `()`
9+
10+
error: aborting due to 1 previous error
11+
12+
For more information about this error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// issue: rust-lang/rust#66757
2+
//
3+
// See also: `tests/ui/never_type/from_infer_breaking_with_unit_fallback.rs`.
4+
//
5+
//@ revisions: unit never
6+
//@ check-pass
7+
#![allow(internal_features)]
8+
#![feature(rustc_attrs, never_type)]
9+
#![cfg_attr(unit, rustc_never_type_options(fallback = "unit"))]
10+
#![cfg_attr(never, rustc_never_type_options(fallback = "never"))]
11+
12+
type Infallible = !;
13+
14+
struct E;
15+
16+
impl From<Infallible> for E {
17+
fn from(_: Infallible) -> E {
18+
E
19+
}
20+
}
21+
22+
fn u32_try_from(x: u32) -> Result<u32, Infallible> {
23+
Ok(x)
24+
}
25+
26+
fn _f() -> Result<(), E> {
27+
// In an old attempt to make `Infallible = !` this caused a problem.
28+
//
29+
// Because at the time the code desugared to
30+
//
31+
// match u32::try_from(1u32) {
32+
// Ok(x) => x, Err(e) => return Err(E::from(e))
33+
// }
34+
//
35+
// With `Infallible = !`, `e: !` but with fallback to `()`, `e` in `E::from(e)` decayed to `()`
36+
// causing an error.
37+
//
38+
// This does not happen with `Infallible = !`.
39+
// And also does not happen with the newer `?` desugaring that does not pass `e` by value.
40+
// (instead we only pass `Result<!, Error>` (where `Error = !` in this case) which does not get
41+
// the implicit coercion and thus does not decay even with fallback to unit)
42+
u32_try_from(1u32)?;
43+
Ok(())
44+
}
45+
46+
fn main() {}

0 commit comments

Comments
 (0)