@@ -6,6 +6,7 @@ mod suggestions;
6
6
7
7
use crate::coercion::DynamicCoerceMany;
8
8
use crate::fallback::DivergingFallbackBehavior;
9
+ use crate::fn_ctxt::checks::DivergingBlockBehavior;
9
10
use crate::{CoroutineTypes, Diverges, EnclosingBreakables, Inherited};
10
11
use hir::def_id::CRATE_DEF_ID;
11
12
use rustc_errors::{DiagCtxt, ErrorGuaranteed};
@@ -112,6 +113,7 @@ pub struct FnCtxt<'a, 'tcx> {
112
113
pub(super) fallback_has_occurred: Cell<bool>,
113
114
114
115
pub(super) diverging_fallback_behavior: DivergingFallbackBehavior,
116
+ pub(super) diverging_block_behavior: DivergingBlockBehavior,
115
117
}
116
118
117
119
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@@ -120,7 +122,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
120
122
param_env: ty::ParamEnv<'tcx>,
121
123
body_id: LocalDefId,
122
124
) -> FnCtxt<'a, 'tcx> {
123
- let diverging_fallback_behavior = parse_never_type_options_attr(inh.tcx);
125
+ let (diverging_fallback_behavior, diverging_block_behavior) =
126
+ parse_never_type_options_attr(inh.tcx);
124
127
FnCtxt {
125
128
body_id,
126
129
param_env,
@@ -137,6 +140,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
137
140
inh,
138
141
fallback_has_occurred: Cell::new(false),
139
142
diverging_fallback_behavior,
143
+ diverging_block_behavior,
140
144
}
141
145
}
142
146
@@ -381,13 +385,16 @@ impl<'tcx> LoweredTy<'tcx> {
381
385
}
382
386
}
383
387
384
- fn parse_never_type_options_attr(tcx: TyCtxt<'_>) -> DivergingFallbackBehavior {
388
+ fn parse_never_type_options_attr(
389
+ tcx: TyCtxt<'_>,
390
+ ) -> (DivergingFallbackBehavior, DivergingBlockBehavior) {
385
391
use DivergingFallbackBehavior::*;
386
392
387
393
// Error handling is dubious here (unwraps), but that's probably fine for an internal attribute.
388
394
// Just don't write incorrect attributes <3
389
395
390
396
let mut fallback = None;
397
+ let mut block = None;
391
398
392
399
let items = tcx
393
400
.get_attr(CRATE_DEF_ID, sym::rustc_never_type_options)
@@ -409,6 +416,18 @@ fn parse_never_type_options_attr(tcx: TyCtxt<'_>) -> DivergingFallbackBehavior {
409
416
continue;
410
417
}
411
418
419
+ if item.has_name(sym::diverging_block_default) && fallback.is_none() {
420
+ let mode = item.value_str().unwrap();
421
+ match mode {
422
+ sym::unit => block = Some(DivergingBlockBehavior::Unit),
423
+ sym::never => block = Some(DivergingBlockBehavior::Never),
424
+ _ => {
425
+ tcx.dcx().span_err(item.span(), format!("unknown diverging block default: `{mode}` (supported: `unit` and `never`)"));
426
+ }
427
+ };
428
+ continue;
429
+ }
430
+
412
431
tcx.dcx().span_err(
413
432
item.span(),
414
433
format!(
@@ -422,5 +441,7 @@ fn parse_never_type_options_attr(tcx: TyCtxt<'_>) -> DivergingFallbackBehavior {
422
441
if tcx.features().never_type_fallback { FallbackToNiko } else { FallbackToUnit }
423
442
});
424
443
425
- fallback
444
+ let block = block.unwrap_or_default();
445
+
446
+ (fallback, block)
426
447
}
0 commit comments