Skip to content

Commit 2eea6dc

Browse files
committed
Unwrap lines
The line wrapping was a bit inconsistent. Let's just unwrap all the lines on this page.
1 parent 8567b15 commit 2eea6dc

File tree

1 file changed

+13
-28
lines changed

1 file changed

+13
-28
lines changed

src/rust-2024/never-type-fallback.md

+13-28
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@
44

55
## Summary
66

7-
- Never type (`!`) to any type coercions fallback to never type (`!`)
7+
- Never type (`!`) to any type coercions fallback to never type (`!`).
88

99
## Details
1010

11-
When the compiler sees a value of type ! in a [coercion site],
12-
it implicitly inserts a coercion to allow the type checker to infer any type:
11+
When the compiler sees a value of type ! in a [coercion site], it implicitly inserts a coercion to allow the type checker to infer any type:
1312

1413
```rust,ignore (has placeholders)
1514
// this
@@ -33,8 +32,7 @@ This can lead to compilation errors if the type cannot be inferred:
3332
{ absurd(panic!()) }; // error: can't infer the type of `absurd`
3433
```
3534

36-
To prevent such errors, the compiler remembers where it inserted absurd calls,
37-
and if it can’t infer the type, it uses the fallback type instead:
35+
To prevent such errors, the compiler remembers where it inserted absurd calls, and if it can’t infer the type, it uses the fallback type instead:
3836

3937
```rust,ignore (has placeholders, uses code from previous example)
4038
type Fallback = /* An arbitrarily selected type! */;
@@ -43,29 +41,21 @@ type Fallback = /* An arbitrarily selected type! */;
4341

4442
This is what is known as “never type fallback”.
4543

46-
Historically, the fallback type was `()`, causing confusing behavior where `!` spontaneously coerced to `()`,
47-
even when it would not infer `()` without the fallback.
44+
Historically, the fallback type was `()`, causing confusing behavior where `!` spontaneously coerced to `()`, even when it would not infer `()` without the fallback.
4845

49-
In the 2024 edition (and possibly in all editions on a later date) the fallback is now `!`.
50-
This makes it work more intuitively, now when you pass `!` and there is no reason to coerce it to
51-
something else, it is kept as `!`.
46+
In the 2024 edition (and possibly in all editions on a later date) the fallback is now `!`. This makes it work more intuitively, now when you pass `!` and there is no reason to coerce it to something else, it is kept as `!`.
5247

53-
In some cases your code might depend on the fallback being `()`, so this can cause compilation
54-
errors or changes in behavior.
48+
In some cases your code might depend on the fallback being `()`, so this can cause compilation errors or changes in behavior.
5549

5650
[coercion site]: https://doc.rust-lang.org/reference/type-coercions.html#coercion-sites
5751

5852
## Migration
5953

60-
There is no automatic fix, but there is automatic detection of code which will be broken by the
61-
edition change. While still on a previous edition you should see warnings if your code will be
62-
broken.
54+
There is no automatic fix, but there is automatic detection of code which will be broken by the edition change. While still on a previous edition you should see warnings if your code will be broken.
6355

64-
In either case the fix is to specify the type explicitly, so the fallback is not used.
65-
The complication is that it might not be trivial to see which type needs to be specified.
56+
In either case the fix is to specify the type explicitly, so the fallback is not used. The complication is that it might not be trivial to see which type needs to be specified.
6657

67-
One of the most common patterns which are broken by this change is using `f()?;` where `f` is
68-
generic over the ok-part of the return type:
58+
One of the most common patterns which are broken by this change is using `f()?;` where `f` is generic over the ok-part of the return type:
6959

7060
```rust,ignore (can't compile outside of a result-returning function)
7161
fn f<T: Default>() -> Result<T, ()> {
@@ -75,8 +65,7 @@ fn f<T: Default>() -> Result<T, ()> {
7565
f()?;
7666
```
7767

78-
You might think that in this example type `T` can't be inferred, however due to the current
79-
desugaring of `?` operator it used to be inferred to `()`, but it will be inferred to `!` now.
68+
You might think that in this example type `T` can't be inferred, however due to the current desugaring of `?` operator it used to be inferred to `()`, but it will be inferred to `!` now.
8069

8170
To fix the issue you need to specify the `T` type explicitly:
8271

@@ -99,16 +88,13 @@ fn run<R: Unit>(f: impl FnOnce() -> R) {
9988
run(|| panic!());
10089
```
10190

102-
Previously `!` from the `panic!` coerced to `()` which implements `Unit`.
103-
However now the `!` is kept as `!` so this code fails because `!` does not implement `Unit`.
104-
To fix this you can specify return type of the closure:
91+
Previously `!` from the `panic!` coerced to `()` which implements `Unit`. However now the `!` is kept as `!` so this code fails because `!` does not implement `Unit`. To fix this you can specify return type of the closure:
10592

10693
```rust,ignore (uses function from the previous example)
10794
run(|| -> () { panic!() });
10895
```
10996

110-
A similar case to the `f()?` can be seen when using a `!`-typed expression in a branch and a
111-
function with unconstrained return in the other:
97+
A similar case to the `f()?` can be seen when using a `!`-typed expression in a branch and a function with unconstrained return in the other:
11298

11399
```rust,edition2015
114100
if true {
@@ -118,8 +104,7 @@ if true {
118104
};
119105
```
120106

121-
Previously `()` was inferred as the return type of `Default::default()` because `!` from `return` got spuriously coerced to `()`.
122-
Now, `!` will be inferred instead causing this code to not compile, because `!` does not implement `Default`.
107+
Previously `()` was inferred as the return type of `Default::default()` because `!` from `return` got spuriously coerced to `()`. Now, `!` will be inferred instead causing this code to not compile, because `!` does not implement `Default`.
123108

124109
Again, this can be fixed by specifying the type explicitly:
125110

0 commit comments

Comments
 (0)