@@ -12,6 +12,9 @@ enum DivergingFallbackBehavior {
12
12
FallbackToUnit ,
13
13
/// Sometimes fallback to `!`, but mainly fallback to `()` so that most of the crates are not broken.
14
14
FallbackToNiko ,
15
+ /// Always fallback to `!` (which should be equivalent to never falling back + not making
16
+ /// never-to-any coercions unless necessary)
17
+ FallbackToNever ,
15
18
/// Don't fallback at all
16
19
Nope ,
17
20
}
@@ -91,9 +94,10 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
91
94
92
95
fn diverging_fallback_behavior ( & self ) -> DivergingFallbackBehavior {
93
96
let niko = self . tcx . features ( ) . never_type_fallback ;
97
+ let never = self . tcx . features ( ) . no_never_type_spontaneous_decay ;
94
98
let nope = self . tcx . features ( ) . no_never_type_fallback ;
95
99
96
- if niko as u32 + nope as u32 > 1 {
100
+ if niko as u32 + never as u32 + nope as u32 > 1 {
97
101
self . tcx . dcx ( ) . err ( "can't enable multiple never type fallback features (`never_type_fallback`, `no_never_type_fallback`)" ) ;
98
102
return DivergingFallbackBehavior :: FallbackToUnit ;
99
103
}
@@ -102,6 +106,10 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
102
106
return DivergingFallbackBehavior :: FallbackToNiko ;
103
107
}
104
108
109
+ if never {
110
+ return DivergingFallbackBehavior :: FallbackToNever ;
111
+ }
112
+
105
113
if nope {
106
114
return DivergingFallbackBehavior :: Nope ;
107
115
}
@@ -419,6 +427,13 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
419
427
diverging_fallback. insert ( diverging_ty, self . tcx . types . never ) ;
420
428
}
421
429
}
430
+ FallbackToNever => {
431
+ debug ! (
432
+ "fallback to ! - `feature(no_never_type_spontaneous_decay)`: {:?}" ,
433
+ diverging_vid
434
+ ) ;
435
+ diverging_fallback. insert ( diverging_ty, self . tcx . types . never ) ;
436
+ }
422
437
Nope => {
423
438
debug ! ( "not fallback - `feature(no_never_type_fallback)`: {:?}" , diverging_vid) ;
424
439
}
0 commit comments