@@ -4250,13 +4250,46 @@ declare_lint! {
4250
4250
/// The `never_type_fallback_flowing_into_unsafe` lint detects cases where never type fallback
4251
4251
/// affects unsafe function calls.
4252
4252
///
4253
+ /// ### Never type fallback
4254
+ ///
4255
+ /// When the compiler sees a value of type [`!`] it implicitly inserts a coercion (if possible),
4256
+ /// to allow type check to infer any type:
4257
+ ///
4258
+ /// ```ignore (illustrative-and-has-placeholders)
4259
+ /// // this
4260
+ /// let x: u8 = panic!();
4261
+ ///
4262
+ /// // is (essentially) turned by the compiler into
4263
+ /// let x: u8 = absurd(panic!());
4264
+ ///
4265
+ /// // where absurd is a function with the following signature
4266
+ /// // (it's sound, because `!` always marks unreachable code):
4267
+ /// fn absurd<T>(_: !) -> T { ... }
4268
+ // FIXME: use `core::convert::absurd` here instead, once it's merged
4269
+ /// ```
4270
+ ///
4271
+ /// While it's convenient to be able to use non-diverging code in one of the branches (like
4272
+ /// `if a { b } else { return }`) this could lead to compilation errors:
4273
+ ///
4274
+ /// ```compile_fail
4275
+ /// // this
4276
+ /// { panic!() };
4277
+ ///
4278
+ /// // gets turned into this
4279
+ /// { absurd(panic!()) }; // error: can't infer the type of `absurd`
4280
+ /// ```
4281
+ ///
4282
+ /// To prevent such errors, compiler remembers where it inserted `absurd` calls, and if it
4283
+ /// can't infer their type, it sets the type to fallback. `{ absurd::<Fallback>(panic!()) };`.
4284
+ /// This is what is known as "never type fallback".
4285
+ ///
4253
4286
/// ### Example
4254
4287
///
4255
4288
/// ```rust,compile_fail
4256
4289
/// #![deny(never_type_fallback_flowing_into_unsafe)]
4257
4290
/// fn main() {
4258
4291
/// if true {
4259
- /// // return has type `!` (never) which, is some cases, causes never type fallback
4292
+ /// // return has type `!` which, is some cases, causes never type fallback
4260
4293
/// return
4261
4294
/// } else {
4262
4295
/// // `zeroed` is an unsafe function, which returns an unbounded type
@@ -4271,7 +4304,7 @@ declare_lint! {
4271
4304
///
4272
4305
/// ### Explanation
4273
4306
///
4274
- /// Due to historic reasons never type fallback were `()`, meaning that `!` got spontaneously
4307
+ /// Due to historic reasons never type fallback was `()`, meaning that `!` got spontaneously
4275
4308
/// coerced to `()`. There are plans to change that, but they may make the code such as above
4276
4309
/// unsound. Instead of depending on the fallback, you should specify the type explicitly:
4277
4310
/// ```
@@ -4284,6 +4317,9 @@ declare_lint! {
4284
4317
/// ```
4285
4318
///
4286
4319
/// See [Tracking Issue for making `!` fall back to `!`](https://github.com/rust-lang/rust/issues/123748).
4320
+ ///
4321
+ /// [`!`]: https://doc.rust-lang.org/core/primitive.never.html
4322
+ /// [`()`]: https://doc.rust-lang.org/core/primitive.unit.html
4287
4323
pub NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE ,
4288
4324
Warn ,
4289
4325
"never type fallback affecting unsafe function calls"
0 commit comments