@@ -185,7 +185,7 @@ use rustc::mir::visit::Visitor as MirVisitor;
185
185
use rustc:: mir:: { self , Local , Location } ;
186
186
use rustc:: ty:: adjustment:: { CustomCoerceUnsized , PointerCast } ;
187
187
use rustc:: ty:: print:: obsolete:: DefPathBasedNames ;
188
- use rustc:: ty:: subst:: { InternalSubsts , SubstsRef } ;
188
+ use rustc:: ty:: subst:: InternalSubsts ;
189
189
use rustc:: ty:: { self , GenericParamDefKind , Instance , Ty , TyCtxt , TypeFoldable } ;
190
190
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
191
191
use rustc_data_structures:: sync:: { par_iter, MTLock , MTRef , ParallelIterator } ;
@@ -493,7 +493,21 @@ struct MirNeighborCollector<'a, 'tcx> {
493
493
tcx : TyCtxt < ' tcx > ,
494
494
body : & ' a mir:: Body < ' tcx > ,
495
495
output : & ' a mut Vec < MonoItem < ' tcx > > ,
496
- param_substs : SubstsRef < ' tcx > ,
496
+ instance : Instance < ' tcx > ,
497
+ }
498
+
499
+ impl < ' a , ' tcx > MirNeighborCollector < ' a , ' tcx > {
500
+ pub fn monomorphize < T > ( & self , value : T ) -> T
501
+ where
502
+ T : TypeFoldable < ' tcx > ,
503
+ {
504
+ debug ! ( "monomorphize: self.instance={:?}" , self . instance) ;
505
+ if let Some ( substs) = self . instance . substs_for_mir_body ( ) {
506
+ self . tcx . subst_and_normalize_erasing_regions ( substs, ty:: ParamEnv :: reveal_all ( ) , & value)
507
+ } else {
508
+ self . tcx . normalize_erasing_regions ( ty:: ParamEnv :: reveal_all ( ) , value)
509
+ }
510
+ }
497
511
}
498
512
499
513
impl < ' a , ' tcx > MirVisitor < ' tcx > for MirNeighborCollector < ' a , ' tcx > {
@@ -509,17 +523,9 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
509
523
ref operand,
510
524
target_ty,
511
525
) => {
512
- let target_ty = self . tcx . subst_and_normalize_erasing_regions (
513
- self . param_substs ,
514
- ty:: ParamEnv :: reveal_all ( ) ,
515
- & target_ty,
516
- ) ;
526
+ let target_ty = self . monomorphize ( target_ty) ;
517
527
let source_ty = operand. ty ( self . body , self . tcx ) ;
518
- let source_ty = self . tcx . subst_and_normalize_erasing_regions (
519
- self . param_substs ,
520
- ty:: ParamEnv :: reveal_all ( ) ,
521
- & source_ty,
522
- ) ;
528
+ let source_ty = self . monomorphize ( source_ty) ;
523
529
let ( source_ty, target_ty) =
524
530
find_vtable_types_for_unsizing ( self . tcx , source_ty, target_ty) ;
525
531
// This could also be a different Unsize instruction, like
@@ -540,11 +546,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
540
546
_,
541
547
) => {
542
548
let fn_ty = operand. ty ( self . body , self . tcx ) ;
543
- let fn_ty = self . tcx . subst_and_normalize_erasing_regions (
544
- self . param_substs ,
545
- ty:: ParamEnv :: reveal_all ( ) ,
546
- & fn_ty,
547
- ) ;
549
+ let fn_ty = self . monomorphize ( fn_ty) ;
548
550
visit_fn_use ( self . tcx , fn_ty, false , & mut self . output ) ;
549
551
}
550
552
mir:: Rvalue :: Cast (
@@ -553,11 +555,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
553
555
_,
554
556
) => {
555
557
let source_ty = operand. ty ( self . body , self . tcx ) ;
556
- let source_ty = self . tcx . subst_and_normalize_erasing_regions (
557
- self . param_substs ,
558
- ty:: ParamEnv :: reveal_all ( ) ,
559
- & source_ty,
560
- ) ;
558
+ let source_ty = self . monomorphize ( source_ty) ;
561
559
match source_ty. kind {
562
560
ty:: Closure ( def_id, substs) => {
563
561
let instance = Instance :: resolve_closure (
@@ -593,7 +591,23 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
593
591
fn visit_const ( & mut self , constant : & & ' tcx ty:: Const < ' tcx > , location : Location ) {
594
592
debug ! ( "visiting const {:?} @ {:?}" , * constant, location) ;
595
593
596
- collect_const ( self . tcx , * constant, self . param_substs , self . output ) ;
594
+ let substituted_constant = self . monomorphize ( * constant) ;
595
+ let param_env = ty:: ParamEnv :: reveal_all ( ) ;
596
+
597
+ match substituted_constant. val {
598
+ ty:: ConstKind :: Value ( val) => collect_const_value ( self . tcx , val, self . output ) ,
599
+ ty:: ConstKind :: Unevaluated ( def_id, substs, promoted) => {
600
+ match self . tcx . const_eval_resolve ( param_env, def_id, substs, promoted, None ) {
601
+ Ok ( val) => collect_const_value ( self . tcx , val, self . output ) ,
602
+ Err ( ErrorHandled :: Reported ) => { }
603
+ Err ( ErrorHandled :: TooGeneric ) => span_bug ! (
604
+ self . tcx. def_span( def_id) ,
605
+ "collection encountered polymorphic constant" ,
606
+ ) ,
607
+ }
608
+ }
609
+ _ => { }
610
+ }
597
611
598
612
self . super_const ( constant) ;
599
613
}
@@ -605,21 +619,13 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
605
619
match * kind {
606
620
mir:: TerminatorKind :: Call { ref func, .. } => {
607
621
let callee_ty = func. ty ( self . body , tcx) ;
608
- let callee_ty = tcx. subst_and_normalize_erasing_regions (
609
- self . param_substs ,
610
- ty:: ParamEnv :: reveal_all ( ) ,
611
- & callee_ty,
612
- ) ;
622
+ let callee_ty = self . monomorphize ( callee_ty) ;
613
623
visit_fn_use ( self . tcx , callee_ty, true , & mut self . output ) ;
614
624
}
615
625
mir:: TerminatorKind :: Drop { ref location, .. }
616
626
| mir:: TerminatorKind :: DropAndReplace { ref location, .. } => {
617
627
let ty = location. ty ( self . body , self . tcx ) . ty ;
618
- let ty = tcx. subst_and_normalize_erasing_regions (
619
- self . param_substs ,
620
- ty:: ParamEnv :: reveal_all ( ) ,
621
- & ty,
622
- ) ;
628
+ let ty = self . monomorphize ( ty) ;
623
629
visit_drop_use ( self . tcx , ty, true , self . output ) ;
624
630
}
625
631
mir:: TerminatorKind :: Goto { .. }
@@ -1156,8 +1162,7 @@ fn collect_neighbours<'tcx>(
1156
1162
debug ! ( "collect_neighbours: {:?}" , instance. def_id( ) ) ;
1157
1163
let body = tcx. instance_mir ( instance. def ) ;
1158
1164
1159
- MirNeighborCollector { tcx, body : & body, output, param_substs : instance. substs }
1160
- . visit_body ( body) ;
1165
+ MirNeighborCollector { tcx, body : & body, output, instance } . visit_body ( body) ;
1161
1166
}
1162
1167
1163
1168
fn def_id_to_string ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> String {
@@ -1167,33 +1172,6 @@ fn def_id_to_string(tcx: TyCtxt<'_>, def_id: DefId) -> String {
1167
1172
output
1168
1173
}
1169
1174
1170
- fn collect_const < ' tcx > (
1171
- tcx : TyCtxt < ' tcx > ,
1172
- constant : & ' tcx ty:: Const < ' tcx > ,
1173
- param_substs : SubstsRef < ' tcx > ,
1174
- output : & mut Vec < MonoItem < ' tcx > > ,
1175
- ) {
1176
- debug ! ( "visiting const {:?}" , constant) ;
1177
-
1178
- let param_env = ty:: ParamEnv :: reveal_all ( ) ;
1179
- let substituted_constant =
1180
- tcx. subst_and_normalize_erasing_regions ( param_substs, param_env, & constant) ;
1181
-
1182
- match substituted_constant. val {
1183
- ty:: ConstKind :: Value ( val) => collect_const_value ( tcx, val, output) ,
1184
- ty:: ConstKind :: Unevaluated ( def_id, substs, promoted) => {
1185
- match tcx. const_eval_resolve ( param_env, def_id, substs, promoted, None ) {
1186
- Ok ( val) => collect_const_value ( tcx, val, output) ,
1187
- Err ( ErrorHandled :: Reported ) => { }
1188
- Err ( ErrorHandled :: TooGeneric ) => {
1189
- span_bug ! ( tcx. def_span( def_id) , "collection encountered polymorphic constant" , )
1190
- }
1191
- }
1192
- }
1193
- _ => { }
1194
- }
1195
- }
1196
-
1197
1175
fn collect_const_value < ' tcx > (
1198
1176
tcx : TyCtxt < ' tcx > ,
1199
1177
value : ConstValue < ' tcx > ,
0 commit comments