Skip to content

Commit d681e84

Browse files
committed
make items_of_instance return result
1 parent 56ef113 commit d681e84

File tree

4 files changed

+60
-39
lines changed

4 files changed

+60
-39
lines changed

compiler/rustc_middle/src/mir/mono.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ pub enum InstantiationMode {
4747
LocalCopy,
4848
}
4949

50+
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash, HashStable, TyEncodable, TyDecodable)]
51+
pub struct NormalizationErrorInMono;
52+
5053
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash, HashStable, TyEncodable, TyDecodable)]
5154
pub enum MonoItem<'tcx> {
5255
Fn(Instance<'tcx>),

compiler/rustc_middle/src/query/erase.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ use std::intrinsics::transmute_unchecked;
33
use std::mem::MaybeUninit;
44

55
use rustc_span::ErrorGuaranteed;
6+
use rustc_span::source_map::Spanned;
67

78
use crate::mir::interpret::EvalToValTreeResult;
9+
use crate::mir::mono::{MonoItem, NormalizationErrorInMono};
810
use crate::query::CyclePlaceholder;
911
use crate::traits::solve;
1012
use crate::ty::adjustment::CoerceUnsizedInfo;
@@ -171,6 +173,17 @@ impl EraseType for Result<ty::EarlyBinder<'_, Ty<'_>>, CyclePlaceholder> {
171173
type Result = [u8; size_of::<Result<ty::EarlyBinder<'static, Ty<'_>>, CyclePlaceholder>>()];
172174
}
173175

176+
impl EraseType
177+
for Result<(&'_ [Spanned<MonoItem<'_>>], &'_ [Spanned<MonoItem<'_>>]), NormalizationErrorInMono>
178+
{
179+
type Result = [u8; size_of::<
180+
Result<
181+
(&'static [Spanned<MonoItem<'static>>], &'static [Spanned<MonoItem<'static>>]),
182+
NormalizationErrorInMono,
183+
>,
184+
>()];
185+
}
186+
174187
impl<T> EraseType for Option<&'_ T> {
175188
type Result = [u8; size_of::<Option<&'static ()>>()];
176189
}

compiler/rustc_middle/src/query/mod.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ use crate::mir::interpret::{
117117
EvalStaticInitializerRawResult, EvalToAllocationRawResult, EvalToConstValueResult,
118118
EvalToValTreeResult, GlobalId, LitToConstInput,
119119
};
120-
use crate::mir::mono::{CodegenUnit, CollectionMode, MonoItem, MonoItemPartitions};
120+
use crate::mir::mono::{
121+
CodegenUnit, CollectionMode, MonoItem, MonoItemPartitions, NormalizationErrorInMono,
122+
};
121123
use crate::query::erase::{Erase, erase, restore};
122124
use crate::query::plumbing::{
123125
CyclePlaceholder, DynamicQuery, query_ensure, query_ensure_error_guaranteed, query_get_at,
@@ -2704,16 +2706,11 @@ rustc_queries! {
27042706
desc { "functions to skip for move-size check" }
27052707
}
27062708

2707-
query items_of_instance(key: (ty::Instance<'tcx>, CollectionMode)) -> (&'tcx [Spanned<MonoItem<'tcx>>], &'tcx [Spanned<MonoItem<'tcx>>]) {
2709+
query items_of_instance(key: (ty::Instance<'tcx>, CollectionMode)) -> Result<(&'tcx [Spanned<MonoItem<'tcx>>], &'tcx [Spanned<MonoItem<'tcx>>]), NormalizationErrorInMono> {
27082710
desc { "collecting items used by `{}`", key.0 }
27092711
cache_on_disk_if { true }
27102712
}
27112713

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-
27172714
query size_estimate(key: ty::Instance<'tcx>) -> usize {
27182715
desc { "estimating codegen size of `{}`", key }
27192716
cache_on_disk_if { true }

compiler/rustc_monomorphize/src/collector.rs

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,11 @@ use rustc_hir::lang_items::LangItem;
221221
use rustc_hir::limit::Limit;
222222
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
223223
use rustc_middle::mir::interpret::{AllocId, ErrorHandled, GlobalAlloc, Scalar};
224-
use rustc_middle::mir::mono::{CollectionMode, InstantiationMode, MonoItem};
224+
use rustc_middle::mir::mono::{
225+
CollectionMode, InstantiationMode, MonoItem, NormalizationErrorInMono,
226+
};
225227
use rustc_middle::mir::visit::Visitor as MirVisitor;
226-
use rustc_middle::mir::{self, Location, MentionedItem, traversal};
228+
use rustc_middle::mir::{self, Body, Location, MentionedItem, traversal};
227229
use rustc_middle::query::TyCtxtAt;
228230
use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion};
229231
use rustc_middle::ty::layout::ValidityRequirement;
@@ -474,25 +476,23 @@ fn collect_items_rec<'tcx>(
474476
recursion_limit,
475477
));
476478

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-
494479
rustc_data_structures::stack::ensure_sufficient_stack(|| {
495-
let (used, mentioned) = tcx.items_of_instance((instance, mode));
480+
let Ok((used, mentioned)) = tcx.items_of_instance((instance, mode)) else {
481+
// Normalization errors here are usually due to trait solving overflow.
482+
// FIXME: I assume that there are few type errors at post-analysis stage, but not
483+
// entirely sure.
484+
// We have to emit the error outside of `items_of_instance` to access the
485+
// span of the `starting_item`.
486+
let def_id = instance.def_id();
487+
let def_span = tcx.def_span(def_id);
488+
let def_path_str = tcx.def_path_str(def_id);
489+
tcx.dcx().emit_fatal(RecursionLimit {
490+
span: starting_item.span,
491+
instance,
492+
def_span,
493+
def_path_str,
494+
});
495+
};
496496
used_items.extend(used.into_iter().copied());
497497
mentioned_items.extend(mentioned.into_iter().copied());
498498
});
@@ -621,9 +621,12 @@ fn collect_items_rec<'tcx>(
621621
}
622622
}
623623

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 {
624+
// Check whether we can normalize every type in the instantiated MIR body.
625+
fn check_normalization_error<'tcx>(
626+
tcx: TyCtxt<'tcx>,
627+
instance: Instance<'tcx>,
628+
body: &Body<'tcx>,
629+
) -> Result<(), NormalizationErrorInMono> {
627630
struct NormalizationChecker<'tcx> {
628631
tcx: TyCtxt<'tcx>,
629632
instance: Instance<'tcx>,
@@ -643,9 +646,8 @@ fn has_normalization_error_in_mono<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'
643646
}
644647
}
645648

646-
let body = tcx.instance_mir(instance.def);
647649
let mut checker = NormalizationChecker { tcx, instance };
648-
body.visit_with(&mut checker).is_break()
650+
if body.visit_with(&mut checker).is_break() { Err(NormalizationErrorInMono) } else { Ok(()) }
649651
}
650652

651653
fn check_recursion_limit<'tcx>(
@@ -1304,11 +1306,15 @@ fn collect_items_of_instance<'tcx>(
13041306
tcx: TyCtxt<'tcx>,
13051307
instance: Instance<'tcx>,
13061308
mode: CollectionMode,
1307-
) -> (MonoItems<'tcx>, MonoItems<'tcx>) {
1309+
) -> Result<(MonoItems<'tcx>, MonoItems<'tcx>), NormalizationErrorInMono> {
13081310
// This item is getting monomorphized, do mono-time checks.
1311+
let body = tcx.instance_mir(instance.def);
1312+
// Plenty of code paths later assume that everything can be normalized. So we have to check
1313+
// normalization first.
1314+
// We choose to emit the error outside to provide helpful diagnostics.
1315+
check_normalization_error(tcx, instance, body)?;
13091316
tcx.ensure_ok().check_mono_item(instance);
13101317

1311-
let body = tcx.instance_mir(instance.def);
13121318
// Naively, in "used" collection mode, all functions get added to *both* `used_items` and
13131319
// `mentioned_items`. Mentioned items processing will then notice that they have already been
13141320
// visited, but at that point each mentioned item has been monomorphized, added to the
@@ -1358,19 +1364,22 @@ fn collect_items_of_instance<'tcx>(
13581364
}
13591365
}
13601366

1361-
(used_items, mentioned_items)
1367+
Ok((used_items, mentioned_items))
13621368
}
13631369

13641370
fn items_of_instance<'tcx>(
13651371
tcx: TyCtxt<'tcx>,
13661372
(instance, mode): (Instance<'tcx>, CollectionMode),
1367-
) -> (&'tcx [Spanned<MonoItem<'tcx>>], &'tcx [Spanned<MonoItem<'tcx>>]) {
1368-
let (used_items, mentioned_items) = collect_items_of_instance(tcx, instance, mode);
1373+
) -> Result<
1374+
(&'tcx [Spanned<MonoItem<'tcx>>], &'tcx [Spanned<MonoItem<'tcx>>]),
1375+
NormalizationErrorInMono,
1376+
> {
1377+
let (used_items, mentioned_items) = collect_items_of_instance(tcx, instance, mode)?;
13691378

13701379
let used_items = tcx.arena.alloc_from_iter(used_items);
13711380
let mentioned_items = tcx.arena.alloc_from_iter(mentioned_items);
13721381

1373-
(used_items, mentioned_items)
1382+
Ok((used_items, mentioned_items))
13741383
}
13751384

13761385
/// `item` must be already monomorphized.
@@ -1815,5 +1824,4 @@ pub(crate) fn collect_crate_mono_items<'tcx>(
18151824
pub(crate) fn provide(providers: &mut Providers) {
18161825
providers.hooks.should_codegen_locally = should_codegen_locally;
18171826
providers.items_of_instance = items_of_instance;
1818-
providers.has_normalization_error_in_mono = has_normalization_error_in_mono;
18191827
}

0 commit comments

Comments
 (0)