Skip to content

Commit 152fd34

Browse files
committed
Move logic to mono_checks
1 parent b8baaaa commit 152fd34

File tree

3 files changed

+49
-47
lines changed

3 files changed

+49
-47
lines changed

compiler/rustc_monomorphize/src/collector.rs

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

210210
use std::cell::OnceCell;
211-
use std::ops::ControlFlow;
212211

213212
use rustc_data_structures::fx::FxIndexMap;
214213
use rustc_data_structures::sync::{MTLock, par_for_each_in};
@@ -229,7 +228,7 @@ use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion};
229228
use rustc_middle::ty::layout::ValidityRequirement;
230229
use rustc_middle::ty::{
231230
self, GenericArgs, GenericParamDefKind, Instance, InstanceKind, Ty, TyCtxt, TypeFoldable,
232-
TypeVisitable, TypeVisitableExt, TypeVisitor, VtblEntry,
231+
TypeVisitableExt, VtblEntry,
233232
};
234233
use rustc_middle::util::Providers;
235234
use rustc_middle::{bug, span_bug};
@@ -474,23 +473,6 @@ fn collect_items_rec<'tcx>(
474473
recursion_limit,
475474
));
476475

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-
494476
rustc_data_structures::stack::ensure_sufficient_stack(|| {
495477
let (used, mentioned) = tcx.items_of_instance((instance, mode));
496478
used_items.extend(used.into_iter().copied());
@@ -621,33 +603,6 @@ fn collect_items_rec<'tcx>(
621603
}
622604
}
623605

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-
651606
fn check_recursion_limit<'tcx>(
652607
tcx: TyCtxt<'tcx>,
653608
instance: Instance<'tcx>,
@@ -1815,5 +1770,4 @@ pub(crate) fn collect_crate_mono_items<'tcx>(
18151770
pub(crate) fn provide(providers: &mut Providers) {
18161771
providers.hooks.should_codegen_locally = should_codegen_locally;
18171772
providers.items_of_instance = items_of_instance;
1818-
providers.has_normalization_error_in_mono = has_normalization_error_in_mono;
18191773
}

compiler/rustc_monomorphize/src/mono_checks/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ use rustc_middle::ty::{Instance, TyCtxt};
77

88
mod abi_check;
99
mod move_check;
10+
mod normalization_check;
1011

1112
fn check_mono_item<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
1213
let body = tcx.instance_mir(instance.def);
14+
15+
normalization_check::check_normalization_error(tcx, instance, body);
1316
abi_check::check_feature_dependent_abi(tcx, instance, body);
1417
move_check::check_moves(tcx, instance, body);
1518
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
use std::ops::ControlFlow;
2+
3+
use rustc_middle::mir::Body;
4+
use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeVisitable, TypeVisitor};
5+
6+
use crate::errors::RecursionLimit;
7+
8+
struct NormalizationChecker<'tcx> {
9+
tcx: TyCtxt<'tcx>,
10+
instance: Instance<'tcx>,
11+
}
12+
13+
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for NormalizationChecker<'tcx> {
14+
type Result = ControlFlow<()>;
15+
16+
fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
17+
match self.instance.try_instantiate_mir_and_normalize_erasing_regions(
18+
self.tcx,
19+
ty::TypingEnv::fully_monomorphized(),
20+
ty::EarlyBinder::bind(t),
21+
) {
22+
Ok(_) => ControlFlow::Continue(()),
23+
Err(_) => ControlFlow::Break(()),
24+
}
25+
}
26+
}
27+
28+
pub(crate) fn check_normalization_error<'tcx>(
29+
tcx: TyCtxt<'tcx>,
30+
instance: Instance<'tcx>,
31+
body: &Body<'tcx>,
32+
) {
33+
let mut checker = NormalizationChecker { tcx, instance };
34+
if body.visit_with(&mut checker).is_break() {
35+
// Plenty of code paths later assume that everything can be normalized.
36+
// Check normalization here to provide better diagnostics.
37+
// Normalization errors here are usually due to trait solving overflow.
38+
// FIXME: I assume that there are few type errors at post-analysis stage, but not
39+
// entirely sure.
40+
let def_id = instance.def_id();
41+
let def_span = tcx.def_span(def_id);
42+
let def_path_str = tcx.def_path_str(def_id);
43+
tcx.dcx().emit_fatal(RecursionLimit { span: def_span, instance, def_span, def_path_str });
44+
}
45+
}

0 commit comments

Comments
 (0)