@@ -220,14 +220,14 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
220
220
use rustc_middle:: mir:: interpret:: { AllocId , ErrorHandled , GlobalAlloc , Scalar } ;
221
221
use rustc_middle:: mir:: mono:: { CollectionMode , InstantiationMode , MonoItem } ;
222
222
use rustc_middle:: mir:: visit:: Visitor as MirVisitor ;
223
- use rustc_middle:: mir:: { self , Location , MentionedItem } ;
223
+ use rustc_middle:: mir:: { self , Location , MentionedItem , traversal } ;
224
224
use rustc_middle:: query:: TyCtxtAt ;
225
225
use rustc_middle:: ty:: adjustment:: { CustomCoerceUnsized , PointerCoercion } ;
226
226
use rustc_middle:: ty:: layout:: ValidityRequirement ;
227
227
use rustc_middle:: ty:: print:: { shrunk_instance_name, with_no_trimmed_paths} ;
228
228
use rustc_middle:: ty:: {
229
- self , GenericArgs , GenericParamDefKind , Instance , InstanceKind , Ty , TyCtxt , TypeVisitableExt ,
230
- VtblEntry ,
229
+ self , GenericArgs , GenericParamDefKind , Instance , InstanceKind , Ty , TyCtxt , TypeFoldable ,
230
+ TypeVisitableExt , VtblEntry ,
231
231
} ;
232
232
use rustc_middle:: util:: Providers ;
233
233
use rustc_middle:: { bug, span_bug} ;
@@ -642,24 +642,38 @@ struct MirUsedCollector<'a, 'tcx> {
642
642
/// See the comment in `collect_items_of_instance` for the purpose of this set.
643
643
/// Note that this contains *not-monomorphized* items!
644
644
used_mentioned_items : & ' a mut UnordSet < MentionedItem < ' tcx > > ,
645
+ instance : Instance < ' tcx > ,
645
646
}
646
647
647
648
impl < ' a , ' tcx > MirUsedCollector < ' a , ' tcx > {
648
- /// Evaluates a monomorphized constant.
649
+ fn monomorphize < T > ( & self , value : T ) -> T
650
+ where
651
+ T : TypeFoldable < TyCtxt < ' tcx > > ,
652
+ {
653
+ trace ! ( "monomorphize: self.instance={:?}" , self . instance) ;
654
+ self . instance . instantiate_mir_and_normalize_erasing_regions (
655
+ self . tcx ,
656
+ ty:: TypingEnv :: fully_monomorphized ( ) ,
657
+ ty:: EarlyBinder :: bind ( value) ,
658
+ )
659
+ }
660
+
661
+ /// Evaluates a *not yet monomorphized* constant.
649
662
fn eval_constant (
650
663
& mut self ,
651
664
constant : & mir:: ConstOperand < ' tcx > ,
652
665
) -> Option < mir:: ConstValue < ' tcx > > {
666
+ let const_ = self . monomorphize ( constant. const_ ) ;
653
667
// Evaluate the constant. This makes const eval failure a collection-time error (rather than
654
668
// a codegen-time error). rustc stops after collection if there was an error, so this
655
669
// ensures codegen never has to worry about failing consts.
656
670
// (codegen relies on this and ICEs will happen if this is violated.)
657
- match constant . const_ . eval ( self . tcx , ty:: TypingEnv :: fully_monomorphized ( ) , constant. span ) {
671
+ match const_. eval ( self . tcx , ty:: TypingEnv :: fully_monomorphized ( ) , constant. span ) {
658
672
Ok ( v) => Some ( v) ,
659
673
Err ( ErrorHandled :: TooGeneric ( ..) ) => span_bug ! (
660
674
constant. span,
661
675
"collection encountered polymorphic constant: {:?}" ,
662
- constant . const_
676
+ const_
663
677
) ,
664
678
Err ( err @ ErrorHandled :: Reported ( ..) ) => {
665
679
err. emit_note ( self . tcx ) ;
@@ -689,6 +703,8 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
689
703
// *Before* monomorphizing, record that we already handled this mention.
690
704
self . used_mentioned_items
691
705
. insert ( MentionedItem :: UnsizeCast { source_ty, target_ty } ) ;
706
+ let target_ty = self . monomorphize ( target_ty) ;
707
+ let source_ty = self . monomorphize ( source_ty) ;
692
708
let ( source_ty, target_ty) =
693
709
find_tails_for_unsizing ( self . tcx . at ( span) , source_ty, target_ty) ;
694
710
// This could also be a different Unsize instruction, like
@@ -714,6 +730,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
714
730
let fn_ty = operand. ty ( self . body , self . tcx ) ;
715
731
// *Before* monomorphizing, record that we already handled this mention.
716
732
self . used_mentioned_items . insert ( MentionedItem :: Fn ( fn_ty) ) ;
733
+ let fn_ty = self . monomorphize ( fn_ty) ;
717
734
visit_fn_use ( self . tcx , fn_ty, false , span, self . used_items ) ;
718
735
}
719
736
mir:: Rvalue :: Cast (
@@ -724,6 +741,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
724
741
let source_ty = operand. ty ( self . body , self . tcx ) ;
725
742
// *Before* monomorphizing, record that we already handled this mention.
726
743
self . used_mentioned_items . insert ( MentionedItem :: Closure ( source_ty) ) ;
744
+ let source_ty = self . monomorphize ( source_ty) ;
727
745
if let ty:: Closure ( def_id, args) = * source_ty. kind ( ) {
728
746
let instance =
729
747
Instance :: resolve_closure ( self . tcx , def_id, args, ty:: ClosureKind :: FnOnce ) ;
@@ -775,12 +793,14 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
775
793
let callee_ty = func. ty ( self . body , tcx) ;
776
794
// *Before* monomorphizing, record that we already handled this mention.
777
795
self . used_mentioned_items . insert ( MentionedItem :: Fn ( callee_ty) ) ;
796
+ let callee_ty = self . monomorphize ( callee_ty) ;
778
797
visit_fn_use ( self . tcx , callee_ty, true , source, & mut self . used_items )
779
798
}
780
799
mir:: TerminatorKind :: Drop { ref place, .. } => {
781
800
let ty = place. ty ( self . body , self . tcx ) . ty ;
782
801
// *Before* monomorphizing, record that we already handled this mention.
783
802
self . used_mentioned_items . insert ( MentionedItem :: Drop ( ty) ) ;
803
+ let ty = self . monomorphize ( ty) ;
784
804
visit_drop_use ( self . tcx , ty, true , source, self . used_items ) ;
785
805
}
786
806
mir:: TerminatorKind :: InlineAsm { ref operands, .. } => {
@@ -790,6 +810,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
790
810
let fn_ty = value. const_ . ty ( ) ;
791
811
// *Before* monomorphizing, record that we already handled this mention.
792
812
self . used_mentioned_items . insert ( MentionedItem :: Fn ( fn_ty) ) ;
813
+ let fn_ty = self . monomorphize ( fn_ty) ;
793
814
visit_fn_use ( self . tcx , fn_ty, false , source, self . used_items ) ;
794
815
}
795
816
mir:: InlineAsmOperand :: SymStatic { def_id } => {
@@ -1210,7 +1231,10 @@ fn collect_items_of_instance<'tcx>(
1210
1231
instance : Instance < ' tcx > ,
1211
1232
mode : CollectionMode ,
1212
1233
) -> ( MonoItems < ' tcx > , MonoItems < ' tcx > ) {
1213
- let body = tcx. codegen_mir ( instance) ;
1234
+ // This item is getting monomorphized, do mono-time checks.
1235
+ tcx. ensure_ok ( ) . check_mono_item ( instance) ;
1236
+
1237
+ let body = tcx. instance_mir ( instance. def ) ;
1214
1238
// Naively, in "used" collection mode, all functions get added to *both* `used_items` and
1215
1239
// `mentioned_items`. Mentioned items processing will then notice that they have already been
1216
1240
// visited, but at that point each mentioned item has been monomorphized, added to the
@@ -1229,6 +1253,7 @@ fn collect_items_of_instance<'tcx>(
1229
1253
body,
1230
1254
used_items : & mut used_items,
1231
1255
used_mentioned_items : & mut used_mentioned_items,
1256
+ instance,
1232
1257
} ;
1233
1258
1234
1259
if mode == CollectionMode :: UsedItems {
@@ -1237,7 +1262,7 @@ fn collect_items_of_instance<'tcx>(
1237
1262
collector. visit_var_debug_info ( var_debug_info) ;
1238
1263
}
1239
1264
}
1240
- for ( bb, data) in body . basic_blocks . iter_enumerated ( ) {
1265
+ for ( bb, data) in traversal :: reverse_postorder ( body ) {
1241
1266
collector. visit_basic_block_data ( bb, data)
1242
1267
}
1243
1268
}
@@ -1254,7 +1279,8 @@ fn collect_items_of_instance<'tcx>(
1254
1279
// `used_items` above.
1255
1280
for item in body. mentioned_items ( ) {
1256
1281
if !collector. used_mentioned_items . contains ( & item. node ) {
1257
- visit_mentioned_item ( tcx, & item. node , item. span , & mut mentioned_items) ;
1282
+ let item_mono = collector. monomorphize ( item. node ) ;
1283
+ visit_mentioned_item ( tcx, & item_mono, item. span , & mut mentioned_items) ;
1258
1284
}
1259
1285
}
1260
1286
0 commit comments