Skip to content

Commit 147b20e

Browse files
committed
check normalization overflow in monomorphization
1 parent 52618eb commit 147b20e

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

compiler/rustc_middle/src/query/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2709,6 +2709,11 @@ rustc_queries! {
27092709
cache_on_disk_if { true }
27102710
}
27112711

2712+
query has_normalization_error_in_mono(key: ty::Instance<'tcx>) -> bool {
2713+
desc { "checking whether {}'s body has post-analysis normalization error", key }
2714+
cache_on_disk_if { true }
2715+
}
2716+
27122717
query size_estimate(key: ty::Instance<'tcx>) -> usize {
27132718
desc { "estimating codegen size of `{}`", key }
27142719
cache_on_disk_if { true }

compiler/rustc_monomorphize/src/collector.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@
208208
mod autodiff;
209209

210210
use std::cell::OnceCell;
211+
use std::ops::ControlFlow;
211212

212213
use rustc_data_structures::fx::FxIndexMap;
213214
use rustc_data_structures::sync::{MTLock, par_for_each_in};
@@ -228,7 +229,7 @@ use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion};
228229
use rustc_middle::ty::layout::ValidityRequirement;
229230
use rustc_middle::ty::{
230231
self, GenericArgs, GenericParamDefKind, Instance, InstanceKind, Ty, TyCtxt, TypeFoldable,
231-
TypeVisitableExt, VtblEntry,
232+
TypeVisitable, TypeVisitableExt, TypeVisitor, VtblEntry,
232233
};
233234
use rustc_middle::util::Providers;
234235
use rustc_middle::{bug, span_bug};
@@ -473,6 +474,23 @@ fn collect_items_rec<'tcx>(
473474
recursion_limit,
474475
));
475476

477+
// Plenty of code paths later assume that everything can be normalized.
478+
// Check normalization here to provide better diagnostics.
479+
// Normalization errors here are usually due to trait solving overflow.
480+
// FIXME: I assume that there are few type errors at post-analysis stage, but not
481+
// entirely sure.
482+
if tcx.has_normalization_error_in_mono(instance) {
483+
let def_id = instance.def_id();
484+
let def_span = tcx.def_span(def_id);
485+
let def_path_str = tcx.def_path_str(def_id);
486+
tcx.dcx().emit_fatal(RecursionLimit {
487+
span: starting_item.span,
488+
instance,
489+
def_span,
490+
def_path_str,
491+
});
492+
}
493+
476494
rustc_data_structures::stack::ensure_sufficient_stack(|| {
477495
let (used, mentioned) = tcx.items_of_instance((instance, mode));
478496
used_items.extend(used.into_iter().copied());
@@ -603,6 +621,33 @@ fn collect_items_rec<'tcx>(
603621
}
604622
}
605623

624+
// Check whether we can normalize the MIR body. Make it a query since decoding MIR from disk cache
625+
// may be expensive.
626+
fn has_normalization_error_in_mono<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> bool {
627+
struct NormalizationChecker<'tcx> {
628+
tcx: TyCtxt<'tcx>,
629+
instance: Instance<'tcx>,
630+
}
631+
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for NormalizationChecker<'tcx> {
632+
type Result = ControlFlow<()>;
633+
634+
fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
635+
match self.instance.try_instantiate_mir_and_normalize_erasing_regions(
636+
self.tcx,
637+
ty::TypingEnv::fully_monomorphized(),
638+
ty::EarlyBinder::bind(t),
639+
) {
640+
Ok(_) => ControlFlow::Continue(()),
641+
Err(_) => ControlFlow::Break(()),
642+
}
643+
}
644+
}
645+
646+
let body = tcx.instance_mir(instance.def);
647+
let mut checker = NormalizationChecker { tcx, instance };
648+
body.visit_with(&mut checker).is_break()
649+
}
650+
606651
fn check_recursion_limit<'tcx>(
607652
tcx: TyCtxt<'tcx>,
608653
instance: Instance<'tcx>,
@@ -1770,4 +1815,5 @@ pub(crate) fn collect_crate_mono_items<'tcx>(
17701815
pub(crate) fn provide(providers: &mut Providers) {
17711816
providers.hooks.should_codegen_locally = should_codegen_locally;
17721817
providers.items_of_instance = items_of_instance;
1818+
providers.has_normalization_error_in_mono = has_normalization_error_in_mono;
17731819
}

0 commit comments

Comments
 (0)