@@ -124,7 +124,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
124124 body_id : LocalDefId ,
125125 ) -> FnCtxt < ' a , ' tcx > {
126126 let ( diverging_fallback_behavior, diverging_block_behavior) =
127- parse_never_type_options_attr ( root_ctxt. tcx ) ;
127+ never_type_behavior ( root_ctxt. tcx ) ;
128128 FnCtxt {
129129 body_id,
130130 param_env,
@@ -380,9 +380,30 @@ impl<'tcx> LoweredTy<'tcx> {
380380 }
381381}
382382
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+
383404fn parse_never_type_options_attr (
384405 tcx : TyCtxt < ' _ > ,
385- ) -> ( DivergingFallbackBehavior , DivergingBlockBehavior ) {
406+ ) -> ( Option < DivergingFallbackBehavior > , Option < DivergingBlockBehavior > ) {
386407 use DivergingFallbackBehavior :: * ;
387408
388409 // 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(
432453 ) ;
433454 }
434455
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-
441456 ( fallback, block)
442457}
0 commit comments