@@ -124,7 +124,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
124
124
body_id : LocalDefId ,
125
125
) -> FnCtxt < ' a , ' tcx > {
126
126
let ( diverging_fallback_behavior, diverging_block_behavior) =
127
- parse_never_type_options_attr ( root_ctxt. tcx ) ;
127
+ never_type_behavior ( root_ctxt. tcx ) ;
128
128
FnCtxt {
129
129
body_id,
130
130
param_env,
@@ -380,9 +380,30 @@ impl<'tcx> LoweredTy<'tcx> {
380
380
}
381
381
}
382
382
383
+ fn never_type_behavior ( tcx : TyCtxt < ' _ > ) -> ( DivergingFallbackBehavior , DivergingBlockBehavior ) {
384
+ let ( fallback, block) = parse_never_type_options_attr ( tcx) ;
385
+ let fallback = fallback. unwrap_or_else ( || default_fallback ( tcx) ) ;
386
+ let block = block. unwrap_or_default ( ) ;
387
+
388
+ ( fallback, block)
389
+ }
390
+
391
+ /// Returns the default fallback which is used when there is no explicit override via `#![never_type_options(...)]`.
392
+ fn default_fallback ( tcx : TyCtxt < ' _ > ) -> DivergingFallbackBehavior {
393
+ use DivergingFallbackBehavior :: * ;
394
+
395
+ // `feature(never_type_fallback)`: fallback to `!` or `()` trying to not break stuff
396
+ if tcx. features ( ) . never_type_fallback {
397
+ return FallbackToNiko ;
398
+ }
399
+
400
+ // Otherwise: fallback to `()`
401
+ FallbackToUnit
402
+ }
403
+
383
404
fn parse_never_type_options_attr (
384
405
tcx : TyCtxt < ' _ > ,
385
- ) -> ( DivergingFallbackBehavior , DivergingBlockBehavior ) {
406
+ ) -> ( Option < DivergingFallbackBehavior > , Option < DivergingBlockBehavior > ) {
386
407
use DivergingFallbackBehavior :: * ;
387
408
388
409
// Error handling is dubious here (unwraps), but that's probably fine for an internal attribute.
@@ -432,11 +453,5 @@ fn parse_never_type_options_attr(
432
453
) ;
433
454
}
434
455
435
- let fallback = fallback. unwrap_or_else ( || {
436
- if tcx. features ( ) . never_type_fallback { FallbackToNiko } else { FallbackToUnit }
437
- } ) ;
438
-
439
- let block = block. unwrap_or_default ( ) ;
440
-
441
456
( fallback, block)
442
457
}
0 commit comments