206206//! regardless of whether it is actually needed or not.
207207
208208use std:: path:: PathBuf ;
209+ use std:: sync:: atomic:: Ordering ;
209210
210211use rustc_attr_parsing:: InlineAttr ;
211212use rustc_data_structures:: fx:: FxIndexMap ;
212- use rustc_data_structures:: sync:: { LRef , MTLock , par_for_each_in} ;
213+ use rustc_data_structures:: sync:: { AtomicU32 , LRef , MTLock , par_for_each_in} ;
213214use rustc_data_structures:: unord:: { UnordMap , UnordSet } ;
214215use rustc_hir as hir;
215216use rustc_hir:: def:: DefKind ;
@@ -233,10 +234,12 @@ use rustc_middle::{bug, span_bug};
233234use rustc_session:: Limit ;
234235use rustc_session:: config:: EntryFnType ;
235236use rustc_span:: source_map:: { Spanned , dummy_spanned, respan} ;
236- use rustc_span:: { DUMMY_SP , Span } ;
237+ use rustc_span:: { DUMMY_SP , ErrorGuaranteed , Span } ;
237238use tracing:: { debug, instrument, trace} ;
238239
239- use crate :: errors:: { self , EncounteredErrorWhileInstantiating , NoOptimizedMir , RecursionLimit } ;
240+ use crate :: errors:: {
241+ self , EncounteredErrorWhileInstantiating , MAX_NUMBER_OF_ERRORS , NoOptimizedMir , RecursionLimit ,
242+ } ;
240243
241244#[ derive( PartialEq ) ]
242245pub ( crate ) enum MonoItemCollectionStrategy {
@@ -253,6 +256,8 @@ struct SharedState<'tcx> {
253256 mentioned : MTLock < UnordSet < MonoItem < ' tcx > > > ,
254257 /// Which items are being used where, for better errors.
255258 usage_map : MTLock < UsageMap < ' tcx > > ,
259+ /// Number of errors that have occurred during collection.
260+ error_count : AtomicU32 ,
256261}
257262
258263pub ( crate ) struct UsageMap < ' tcx > {
@@ -466,9 +471,15 @@ fn collect_items_rec<'tcx>(
466471 ) ) ;
467472
468473 rustc_data_structures:: stack:: ensure_sufficient_stack ( || {
469- let ( used, mentioned) = tcx. items_of_instance ( ( instance, mode) ) ;
470- used_items. extend ( used. into_iter ( ) . copied ( ) ) ;
471- mentioned_items. extend ( mentioned. into_iter ( ) . copied ( ) ) ;
474+ match tcx. items_of_instance ( ( instance, mode) ) {
475+ Ok ( ( used, mentioned) ) => {
476+ used_items. extend ( used. into_iter ( ) . copied ( ) ) ;
477+ mentioned_items. extend ( mentioned. into_iter ( ) . copied ( ) ) ;
478+ }
479+ Err ( _) => {
480+ state. error_count . fetch_add ( 1 , Ordering :: Relaxed ) ;
481+ }
482+ } ;
472483 } ) ;
473484 }
474485 MonoItem :: GlobalAsm ( item_id) => {
@@ -527,6 +538,15 @@ fn collect_items_rec<'tcx>(
527538 span : starting_item. span ,
528539 formatted_item,
529540 } ) ;
541+ if state. error_count . load ( Ordering :: Relaxed ) > MAX_NUMBER_OF_ERRORS {
542+ tcx. dcx ( ) . span_fatal (
543+ starting_item. span ,
544+ format ! (
545+ "aborting after reaching the limit of {} errors during monomorphization" ,
546+ MAX_NUMBER_OF_ERRORS
547+ ) ,
548+ ) ;
549+ }
530550 }
531551 // Only updating `usage_map` for used items as otherwise we may be inserting the same item
532552 // multiple times (if it is first 'mentioned' and then later actuall used), and the usage map
@@ -626,6 +646,8 @@ struct MirUsedCollector<'a, 'tcx> {
626646 /// Note that this contains *not-monomorphized* items!
627647 used_mentioned_items : & ' a mut UnordSet < MentionedItem < ' tcx > > ,
628648 instance : Instance < ' tcx > ,
649+ /// If an error is encountered during const evaluation.
650+ tained_by_errors : Option < ErrorGuaranteed > ,
629651}
630652
631653impl < ' a , ' tcx > MirUsedCollector < ' a , ' tcx > {
@@ -658,9 +680,10 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
658680 "collection encountered polymorphic constant: {:?}" ,
659681 const_
660682 ) ,
661- Err ( err @ ErrorHandled :: Reported ( .. ) ) => {
683+ Err ( err @ ErrorHandled :: Reported ( reported , _ ) ) => {
662684 err. emit_note ( self . tcx ) ;
663- return None ;
685+ self . tained_by_errors = Some ( reported. into ( ) ) ;
686+ None
664687 }
665688 }
666689 }
@@ -1211,7 +1234,7 @@ fn collect_items_of_instance<'tcx>(
12111234 tcx : TyCtxt < ' tcx > ,
12121235 instance : Instance < ' tcx > ,
12131236 mode : CollectionMode ,
1214- ) -> ( MonoItems < ' tcx > , MonoItems < ' tcx > ) {
1237+ ) -> Result < ( MonoItems < ' tcx > , MonoItems < ' tcx > ) , ErrorGuaranteed > {
12151238 // This item is getting monomorphized, do mono-time checks.
12161239 tcx. ensure ( ) . check_mono_item ( instance) ;
12171240
@@ -1235,6 +1258,7 @@ fn collect_items_of_instance<'tcx>(
12351258 used_items : & mut used_items,
12361259 used_mentioned_items : & mut used_mentioned_items,
12371260 instance,
1261+ tained_by_errors : None ,
12381262 } ;
12391263
12401264 if mode == CollectionMode :: UsedItems {
@@ -1260,19 +1284,23 @@ fn collect_items_of_instance<'tcx>(
12601284 }
12611285 }
12621286
1263- ( used_items, mentioned_items)
1287+ if let Some ( err) = collector. tained_by_errors {
1288+ return Err ( err) ;
1289+ }
1290+
1291+ Ok ( ( used_items, mentioned_items) )
12641292}
12651293
12661294fn items_of_instance < ' tcx > (
12671295 tcx : TyCtxt < ' tcx > ,
12681296 ( instance, mode) : ( Instance < ' tcx > , CollectionMode ) ,
1269- ) -> ( & ' tcx [ Spanned < MonoItem < ' tcx > > ] , & ' tcx [ Spanned < MonoItem < ' tcx > > ] ) {
1270- let ( used_items, mentioned_items) = collect_items_of_instance ( tcx, instance, mode) ;
1297+ ) -> Result < ( & ' tcx [ Spanned < MonoItem < ' tcx > > ] , & ' tcx [ Spanned < MonoItem < ' tcx > > ] ) , ErrorGuaranteed > {
1298+ let ( used_items, mentioned_items) = collect_items_of_instance ( tcx, instance, mode) ? ;
12711299
12721300 let used_items = tcx. arena . alloc_from_iter ( used_items) ;
12731301 let mentioned_items = tcx. arena . alloc_from_iter ( mentioned_items) ;
12741302
1275- ( used_items, mentioned_items)
1303+ Ok ( ( used_items, mentioned_items) )
12761304}
12771305
12781306/// `item` must be already monomorphized.
@@ -1651,6 +1679,7 @@ pub(crate) fn collect_crate_mono_items<'tcx>(
16511679 visited : MTLock :: new ( UnordSet :: default ( ) ) ,
16521680 mentioned : MTLock :: new ( UnordSet :: default ( ) ) ,
16531681 usage_map : MTLock :: new ( UsageMap :: new ( ) ) ,
1682+ error_count : AtomicU32 :: new ( 0 ) ,
16541683 } ;
16551684 let recursion_limit = tcx. recursion_limit ( ) ;
16561685
0 commit comments