@@ -93,7 +93,6 @@ use rustc_index::IndexVec;
9393use  rustc_middle:: mir:: interpret:: GlobalAlloc ; 
9494use  rustc_middle:: mir:: visit:: * ; 
9595use  rustc_middle:: mir:: * ; 
96- use  rustc_middle:: ty:: adjustment:: PointerCoercion ; 
9796use  rustc_middle:: ty:: layout:: LayoutOf ; 
9897use  rustc_middle:: ty:: { self ,  Ty ,  TyCtxt ,  TypeAndMut } ; 
9998use  rustc_span:: def_id:: DefId ; 
@@ -154,6 +153,9 @@ fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
154153    state. next_opaque  = None ; 
155154
156155    let  reverse_postorder = body. basic_blocks . reverse_postorder ( ) . to_vec ( ) ; 
156+     for  dbg in  body. var_debug_info . iter_mut ( )  { 
157+         state. visit_var_debug_info ( dbg) ; 
158+     } 
157159    for  bb in  reverse_postorder { 
158160        let  data = & mut  body. basic_blocks . as_mut_preserves_cfg ( ) [ bb] ; 
159161        state. visit_basic_block_data ( bb,  data) ; 
@@ -551,6 +553,29 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
551553                    } 
552554                    value. offset ( Size :: ZERO ,  to,  & self . ecx ) . ok ( ) ?
553555                } 
556+                 CastKind :: PointerCoercion ( ty:: adjustment:: PointerCoercion :: Unsize )  => { 
557+                     let  src = self . evaluated [ value] . as_ref ( ) ?; 
558+                     let  to = self . ecx . layout_of ( to) . ok ( ) ?; 
559+                     let  dest = self . ecx . allocate ( to,  MemoryKind :: Stack ) . ok ( ) ?; 
560+                     self . ecx . unsize_into ( src,  to,  & dest. clone ( ) . into ( ) ) . ok ( ) ?; 
561+                     self . ecx 
562+                         . alloc_mark_immutable ( dest. ptr ( ) . provenance . unwrap ( ) . alloc_id ( ) ) 
563+                         . ok ( ) ?; 
564+                     dest. into ( ) 
565+                 } 
566+                 CastKind :: FnPtrToPtr 
567+                 | CastKind :: PtrToPtr 
568+                 | CastKind :: PointerCoercion ( 
569+                     ty:: adjustment:: PointerCoercion :: MutToConstPointer 
570+                     | ty:: adjustment:: PointerCoercion :: ArrayToPointer 
571+                     | ty:: adjustment:: PointerCoercion :: UnsafeFnPointer , 
572+                 )  => { 
573+                     let  src = self . evaluated [ value] . as_ref ( ) ?; 
574+                     let  src = self . ecx . read_immediate ( src) . ok ( ) ?; 
575+                     let  to = self . ecx . layout_of ( to) . ok ( ) ?; 
576+                     let  ret = self . ecx . ptr_to_ptr ( & src,  to) . ok ( ) ?; 
577+                     ret. into ( ) 
578+                 } 
554579                _ => return  None , 
555580            } , 
556581        } ; 
@@ -777,18 +802,8 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
777802
778803            // Operations. 
779804            Rvalue :: Len ( ref  mut  place)  => return  self . simplify_len ( place,  location) , 
780-             Rvalue :: Cast ( kind,  ref  mut  value,  to)  => { 
781-                 let  from = value. ty ( self . local_decls ,  self . tcx ) ; 
782-                 let  value = self . simplify_operand ( value,  location) ?; 
783-                 if  let  CastKind :: PointerCoercion ( 
784-                     PointerCoercion :: ReifyFnPointer  | PointerCoercion :: ClosureFnPointer ( _) , 
785-                 )  = kind
786-                 { 
787-                     // Each reification of a generic fn may get a different pointer. 
788-                     // Do not try to merge them. 
789-                     return  self . new_opaque ( ) ; 
790-                 } 
791-                 Value :: Cast  {  kind,  value,  from,  to } 
805+             Rvalue :: Cast ( ref  mut  kind,  ref  mut  value,  to)  => { 
806+                 return  self . simplify_cast ( kind,  value,  to,  location) ; 
792807            } 
793808            Rvalue :: BinaryOp ( op,  box ( ref  mut  lhs,  ref  mut  rhs) )  => { 
794809                let  ty = lhs. ty ( self . local_decls ,  self . tcx ) ; 
@@ -876,6 +891,12 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
876891            } 
877892        } 
878893
894+         let  fields:  Option < Vec < _ > >  = fields
895+             . iter_mut ( ) 
896+             . map ( |op| self . simplify_operand ( op,  location) . or_else ( || self . new_opaque ( ) ) ) 
897+             . collect ( ) ; 
898+         let  fields = fields?; 
899+ 
879900        let  ( ty,  variant_index)  = match  * kind { 
880901            AggregateKind :: Array ( ..)  => { 
881902                assert ! ( !fields. is_empty( ) ) ; 
@@ -895,12 +916,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
895916            AggregateKind :: Adt ( _,  _,  _,  _,  Some ( _) )  => return  None , 
896917        } ; 
897918
898-         let  fields:  Option < Vec < _ > >  = fields
899-             . iter_mut ( ) 
900-             . map ( |op| self . simplify_operand ( op,  location) . or_else ( || self . new_opaque ( ) ) ) 
901-             . collect ( ) ; 
902-         let  fields = fields?; 
903- 
904919        if  let  AggregateTy :: Array  = ty
905920            && fields. len ( )  > 4 
906921        { 
@@ -1031,6 +1046,50 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
10311046        } 
10321047    } 
10331048
1049+     fn  simplify_cast ( 
1050+         & mut  self , 
1051+         kind :  & mut  CastKind , 
1052+         operand :  & mut  Operand < ' tcx > , 
1053+         to :  Ty < ' tcx > , 
1054+         location :  Location , 
1055+     )  -> Option < VnIndex >  { 
1056+         use  rustc_middle:: ty:: adjustment:: PointerCoercion :: * ; 
1057+         use  CastKind :: * ; 
1058+ 
1059+         let  mut  from = operand. ty ( self . local_decls ,  self . tcx ) ; 
1060+         let  mut  value = self . simplify_operand ( operand,  location) ?; 
1061+         if  from == to { 
1062+             return  Some ( value) ; 
1063+         } 
1064+ 
1065+         if  let  CastKind :: PointerCoercion ( ReifyFnPointer  | ClosureFnPointer ( _) )  = kind { 
1066+             // Each reification of a generic fn may get a different pointer. 
1067+             // Do not try to merge them. 
1068+             return  self . new_opaque ( ) ; 
1069+         } 
1070+ 
1071+         if  let  PtrToPtr  | PointerCoercion ( MutToConstPointer )  = kind
1072+             && let  Value :: Cast  {  kind :  inner_kind,  value :  inner_value,  from :  inner_from,  to :  _ }  =
1073+                 * self . get ( value) 
1074+             && let  PtrToPtr  | PointerCoercion ( MutToConstPointer )  = inner_kind
1075+         { 
1076+             from = inner_from; 
1077+             value = inner_value; 
1078+             * kind = PtrToPtr ; 
1079+             if  inner_from == to { 
1080+                 return  Some ( inner_value) ; 
1081+             } 
1082+             if  let  Some ( const_)  = self . try_as_constant ( value)  { 
1083+                 * operand = Operand :: Constant ( Box :: new ( const_) ) ; 
1084+             }  else  if  let  Some ( local)  = self . try_as_local ( value,  location)  { 
1085+                 * operand = Operand :: Copy ( local. into ( ) ) ; 
1086+                 self . reused_locals . insert ( local) ; 
1087+             } 
1088+         } 
1089+ 
1090+         Some ( self . insert ( Value :: Cast  {  kind :  * kind,  value,  from,  to } ) ) 
1091+     } 
1092+ 
10341093    fn  simplify_len ( & mut  self ,  place :  & mut  Place < ' tcx > ,  location :  Location )  -> Option < VnIndex >  { 
10351094        // Trivial case: we are fetching a statically known length. 
10361095        let  place_ty = place. ty ( self . local_decls ,  self . tcx ) . ty ; 
@@ -1178,6 +1237,51 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
11781237        self . tcx 
11791238    } 
11801239
1240+     fn  visit_var_debug_info ( & mut  self ,  var_debug_info :  & mut  VarDebugInfo < ' tcx > )  { 
1241+         let  mut  replace_dereffed = |place :  & mut  Place < ' tcx > | -> Option < !>  { 
1242+             let  last_deref = place. projection . iter ( ) . rposition ( |e| e == PlaceElem :: Deref ) ?; 
1243+ 
1244+             // Another place that holds the same value. 
1245+             let  mut  place_ref = place. as_ref ( ) ; 
1246+             let  mut  value = self . locals [ place. local ] ?; 
1247+ 
1248+             for  ( index,  & proj)  in  place. projection [ ..last_deref] . iter ( ) . enumerate ( )  { 
1249+                 if  let  Some ( candidates)  = self . rev_locals . get ( value) 
1250+                     && let  Some ( & local)  = candidates. first ( ) 
1251+                 { 
1252+                     place_ref = PlaceRef  {  local,  projection :  & place. projection [ index..]  } ; 
1253+                 } 
1254+ 
1255+                 let  place_upto =
1256+                     PlaceRef  {  local :  place. local ,  projection :  & place. projection [ ..index]  } ; 
1257+                 if  let  Some ( projected)  = self . project ( place_upto,  value,  proj)  { 
1258+                     value = projected; 
1259+                 }  else  { 
1260+                     if  place_ref. projection . len ( )  < place. projection . len ( )  { 
1261+                         * place = place_ref. project_deeper ( & [ ] ,  self . tcx ) ; 
1262+                     } 
1263+                     return  None ; 
1264+                 } 
1265+             } 
1266+ 
1267+             if  let  Some ( candidates)  = self . rev_locals . get ( value) 
1268+                 && let  Some ( & local)  = candidates. first ( ) 
1269+             { 
1270+                 let  place_ref = PlaceRef  {  local,  projection :  & place. projection [ last_deref..]  } ; 
1271+                 * place = place_ref. project_deeper ( & [ ] ,  self . tcx ) ; 
1272+             } 
1273+ 
1274+             return  None ; 
1275+         } ; 
1276+ 
1277+         match  & mut  var_debug_info. value  { 
1278+             VarDebugInfoContents :: Const ( _)  => { } 
1279+             VarDebugInfoContents :: Place ( place)  => { 
1280+                 replace_dereffed ( place) ; 
1281+             } 
1282+         } 
1283+     } 
1284+ 
11811285    fn  visit_place ( & mut  self ,  place :  & mut  Place < ' tcx > ,  _:  PlaceContext ,  location :  Location )  { 
11821286        self . simplify_place_projection ( place,  location) ; 
11831287    } 
0 commit comments