@@ -546,11 +546,104 @@ impl<'tcx, 'locals> CollectAndPatch<'tcx, 'locals> {
546
546
state : & State < FlatSet < Scalar > > ,
547
547
map : & Map ,
548
548
) -> Option < ConstantKind < ' tcx > > {
549
- let FlatSet :: Elem ( Scalar :: Int ( value) ) = state. get ( place. as_ref ( ) , & map) else {
550
- return None ;
551
- } ;
552
549
let ty = place. ty ( self . local_decls , self . tcx ) . ty ;
553
- Some ( ConstantKind :: Val ( ConstValue :: Scalar ( value. into ( ) ) , ty) )
550
+ let place = map. find ( place. as_ref ( ) ) ?;
551
+ if let FlatSet :: Elem ( Scalar :: Int ( value) ) = state. get_idx ( place, map) {
552
+ Some ( ConstantKind :: Val ( ConstValue :: Scalar ( value. into ( ) ) , ty) )
553
+ } else {
554
+ let valtree = self . try_make_valtree ( place, ty, state, map) ?;
555
+ let constant = ty:: Const :: new_value ( self . tcx , valtree, ty) ;
556
+ Some ( ConstantKind :: Ty ( constant) )
557
+ }
558
+ }
559
+
560
+ fn try_make_valtree (
561
+ & self ,
562
+ place : PlaceIndex ,
563
+ ty : Ty < ' tcx > ,
564
+ state : & State < FlatSet < Scalar > > ,
565
+ map : & Map ,
566
+ ) -> Option < ty:: ValTree < ' tcx > > {
567
+ match ty. kind ( ) {
568
+ // ZSTs.
569
+ ty:: FnDef ( ..) => Some ( ty:: ValTree :: zst ( ) ) ,
570
+
571
+ // Scalars.
572
+ ty:: Bool | ty:: Int ( _) | ty:: Uint ( _) | ty:: Float ( _) | ty:: Char => {
573
+ if let FlatSet :: Elem ( Scalar :: Int ( value) ) = state. get_idx ( place, map) {
574
+ Some ( ty:: ValTree :: Leaf ( value) )
575
+ } else {
576
+ None
577
+ }
578
+ }
579
+
580
+ // Unsupported for now.
581
+ ty:: Array ( _, _) => None ,
582
+
583
+ ty:: Tuple ( elem_tys) => {
584
+ let branches = elem_tys
585
+ . iter ( )
586
+ . enumerate ( )
587
+ . map ( |( i, ty) | {
588
+ let field = map. apply ( place, TrackElem :: Field ( FieldIdx :: from_usize ( i) ) ) ?;
589
+ self . try_make_valtree ( field, ty, state, map)
590
+ } )
591
+ . collect :: < Option < Vec < _ > > > ( ) ?;
592
+ Some ( ty:: ValTree :: Branch ( self . tcx . arena . alloc_from_iter ( branches. into_iter ( ) ) ) )
593
+ }
594
+
595
+ ty:: Adt ( def, args) => {
596
+ if def. is_union ( ) {
597
+ return None ;
598
+ }
599
+
600
+ let ( variant_idx, variant_def, variant_place) = if def. is_enum ( ) {
601
+ let discr = map. apply ( place, TrackElem :: Discriminant ) ?;
602
+ let FlatSet :: Elem ( Scalar :: Int ( discr) ) = state. get_idx ( discr, map) else {
603
+ return None ;
604
+ } ;
605
+ let discr_bits = discr. assert_bits ( discr. size ( ) ) ;
606
+ let ( variant, _) =
607
+ def. discriminants ( self . tcx ) . find ( |( _, var) | discr_bits == var. val ) ?;
608
+ let variant_place = map. apply ( place, TrackElem :: Variant ( variant) ) ?;
609
+ let variant_int = ty:: ValTree :: Leaf ( variant. as_u32 ( ) . into ( ) ) ;
610
+ ( Some ( variant_int) , def. variant ( variant) , variant_place)
611
+ } else {
612
+ ( None , def. non_enum_variant ( ) , place)
613
+ } ;
614
+
615
+ let branches = variant_def
616
+ . fields
617
+ . iter_enumerated ( )
618
+ . map ( |( i, field) | {
619
+ let ty = field. ty ( self . tcx , args) ;
620
+ let field = map. apply ( variant_place, TrackElem :: Field ( i) ) ?;
621
+ self . try_make_valtree ( field, ty, state, map)
622
+ } )
623
+ . collect :: < Option < Vec < _ > > > ( ) ?;
624
+ Some ( ty:: ValTree :: Branch (
625
+ self . tcx . arena . alloc_from_iter ( variant_idx. into_iter ( ) . chain ( branches) ) ,
626
+ ) )
627
+ }
628
+
629
+ // Do not attempt to support indirection in constants.
630
+ ty:: Ref ( ..) | ty:: RawPtr ( ..) | ty:: FnPtr ( ..) | ty:: Str | ty:: Slice ( _) => None ,
631
+
632
+ ty:: Never
633
+ | ty:: Foreign ( ..)
634
+ | ty:: Alias ( ..)
635
+ | ty:: Param ( _)
636
+ | ty:: Bound ( ..)
637
+ | ty:: Placeholder ( ..)
638
+ | ty:: Closure ( ..)
639
+ | ty:: Generator ( ..)
640
+ | ty:: Dynamic ( ..) => None ,
641
+
642
+ ty:: Error ( _)
643
+ | ty:: Infer ( ..)
644
+ | ty:: GeneratorWitness ( ..)
645
+ | ty:: GeneratorWitnessMIR ( ..) => bug ! ( ) ,
646
+ }
554
647
}
555
648
556
649
fn make_operand ( & self , literal : ConstantKind < ' tcx > ) -> Operand < ' tcx > {
0 commit comments