@@ -185,7 +185,7 @@ use rustc::mir::visit::Visitor as MirVisitor;
185185use rustc:: mir:: { self , Local , Location } ;
186186use rustc:: ty:: adjustment:: { CustomCoerceUnsized , PointerCast } ;
187187use rustc:: ty:: print:: obsolete:: DefPathBasedNames ;
188- use rustc:: ty:: subst:: { InternalSubsts , SubstsRef } ;
188+ use rustc:: ty:: subst:: InternalSubsts ;
189189use rustc:: ty:: { self , GenericParamDefKind , Instance , Ty , TyCtxt , TypeFoldable } ;
190190use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
191191use rustc_data_structures:: sync:: { par_iter, MTLock , MTRef , ParallelIterator } ;
@@ -493,7 +493,21 @@ struct MirNeighborCollector<'a, 'tcx> {
493493 tcx : TyCtxt < ' tcx > ,
494494 body : & ' a mir:: Body < ' tcx > ,
495495 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+ }
497511}
498512
499513impl < ' a , ' tcx > MirVisitor < ' tcx > for MirNeighborCollector < ' a , ' tcx > {
@@ -509,17 +523,9 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
509523 ref operand,
510524 target_ty,
511525 ) => {
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) ;
517527 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) ;
523529 let ( source_ty, target_ty) =
524530 find_vtable_types_for_unsizing ( self . tcx , source_ty, target_ty) ;
525531 // This could also be a different Unsize instruction, like
@@ -540,11 +546,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
540546 _,
541547 ) => {
542548 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) ;
548550 visit_fn_use ( self . tcx , fn_ty, false , & mut self . output ) ;
549551 }
550552 mir:: Rvalue :: Cast (
@@ -553,11 +555,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
553555 _,
554556 ) => {
555557 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) ;
561559 match source_ty. kind {
562560 ty:: Closure ( def_id, substs) => {
563561 let instance = Instance :: resolve_closure (
@@ -593,7 +591,23 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
593591 fn visit_const ( & mut self , constant : & & ' tcx ty:: Const < ' tcx > , location : Location ) {
594592 debug ! ( "visiting const {:?} @ {:?}" , * constant, location) ;
595593
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+ }
597611
598612 self . super_const ( constant) ;
599613 }
@@ -605,21 +619,13 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
605619 match * kind {
606620 mir:: TerminatorKind :: Call { ref func, .. } => {
607621 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) ;
613623 visit_fn_use ( self . tcx , callee_ty, true , & mut self . output ) ;
614624 }
615625 mir:: TerminatorKind :: Drop { ref location, .. }
616626 | mir:: TerminatorKind :: DropAndReplace { ref location, .. } => {
617627 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) ;
623629 visit_drop_use ( self . tcx , ty, true , self . output ) ;
624630 }
625631 mir:: TerminatorKind :: Goto { .. }
@@ -1156,8 +1162,7 @@ fn collect_neighbours<'tcx>(
11561162 debug ! ( "collect_neighbours: {:?}" , instance. def_id( ) ) ;
11571163 let body = tcx. instance_mir ( instance. def ) ;
11581164
1159- MirNeighborCollector { tcx, body : & body, output, param_substs : instance. substs }
1160- . visit_body ( body) ;
1165+ MirNeighborCollector { tcx, body : & body, output, instance } . visit_body ( body) ;
11611166}
11621167
11631168fn 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 {
11671172 output
11681173}
11691174
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-
11971175fn collect_const_value < ' tcx > (
11981176 tcx : TyCtxt < ' tcx > ,
11991177 value : ConstValue < ' tcx > ,
0 commit comments