@@ -29,6 +29,7 @@ use trans::declare;
29
29
use trans:: monomorphize;
30
30
use trans:: type_:: Type ;
31
31
use trans:: type_of;
32
+ use middle:: cast:: { CastTy , IntTy } ;
32
33
use middle:: subst:: Substs ;
33
34
use middle:: ty:: { self , Ty } ;
34
35
use util:: ppaux:: { Repr , ty_to_string} ;
@@ -616,53 +617,62 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
616
617
}
617
618
}
618
619
ast:: ExprCast ( ref base, _) => {
619
- let llty = type_of:: type_of ( cx, ety) ;
620
- let ( v, basety) = const_expr ( cx, & * * base, param_substs) ;
621
- if expr:: cast_is_noop ( basety, ety) {
620
+ let t_1 = ety;
621
+ let llty = type_of:: type_of ( cx, t_1) ;
622
+ let ( v, t_e) = const_expr ( cx, & * * base, param_substs) ;
623
+ debug ! ( "trans_const_cast({} as {})" , t_e. repr( cx. tcx( ) ) , t_1. repr( cx. tcx( ) ) ) ;
624
+ if expr:: cast_is_noop ( cx. tcx ( ) , base, t_e, t_1) {
622
625
return v;
623
626
}
624
- match ( expr:: cast_type_kind ( cx. tcx ( ) , basety) ,
625
- expr:: cast_type_kind ( cx. tcx ( ) , ety) ) {
626
-
627
- ( expr:: cast_integral, expr:: cast_integral) => {
628
- let s = ty:: type_is_signed ( basety) as Bool ;
627
+ if type_is_fat_ptr ( cx. tcx ( ) , t_e) {
628
+ // Fat pointer casts.
629
+ let t_1_inner = ty:: deref ( t_1, true ) . expect ( "cast to non-pointer" ) . ty ;
630
+ let ptr_ty = type_of:: in_memory_type_of ( cx, t_1_inner) . ptr_to ( ) ;
631
+ let addr = ptrcast ( const_get_elt ( cx, v, & [ abi:: FAT_PTR_ADDR as u32 ] ) ,
632
+ ptr_ty) ;
633
+ if type_is_fat_ptr ( cx. tcx ( ) , t_1) {
634
+ let info = const_get_elt ( cx, v, & [ abi:: FAT_PTR_EXTRA as u32 ] ) ;
635
+ return C_struct ( cx, & [ addr, info] , false )
636
+ } else {
637
+ return addr;
638
+ }
639
+ }
640
+ match ( CastTy :: recognize ( cx. tcx ( ) , t_e) . expect ( "bad input type for cast" ) ,
641
+ CastTy :: recognize ( cx. tcx ( ) , t_1) . expect ( "bad output type for cast" ) ) {
642
+ ( CastTy :: Int ( IntTy :: CEnum ) , CastTy :: Int ( _) ) => {
643
+ let repr = adt:: represent_type ( cx, t_e) ;
644
+ let discr = adt:: const_get_discrim ( cx, & * repr, v) ;
645
+ let iv = C_integral ( cx. int_type ( ) , discr, false ) ;
646
+ let s = adt:: is_discr_signed ( & * repr) as Bool ;
647
+ llvm:: LLVMConstIntCast ( iv, llty. to_ref ( ) , s)
648
+ }
649
+ ( CastTy :: Int ( _) , CastTy :: Int ( _) ) => {
650
+ let s = ty:: type_is_signed ( t_e) as Bool ;
629
651
llvm:: LLVMConstIntCast ( v, llty. to_ref ( ) , s)
630
652
}
631
- ( expr :: cast_integral , expr :: cast_float ) => {
632
- if ty:: type_is_signed ( basety ) {
653
+ ( CastTy :: Int ( _ ) , CastTy :: Float ) => {
654
+ if ty:: type_is_signed ( t_e ) {
633
655
llvm:: LLVMConstSIToFP ( v, llty. to_ref ( ) )
634
656
} else {
635
657
llvm:: LLVMConstUIToFP ( v, llty. to_ref ( ) )
636
658
}
637
659
}
638
- ( expr :: cast_float , expr :: cast_float ) => {
660
+ ( CastTy :: Float , CastTy :: Float ) => {
639
661
llvm:: LLVMConstFPCast ( v, llty. to_ref ( ) )
640
662
}
641
- ( expr :: cast_float , expr :: cast_integral ) => {
642
- if ty:: type_is_signed ( ety ) { llvm:: LLVMConstFPToSI ( v, llty. to_ref ( ) ) }
663
+ ( CastTy :: Float , CastTy :: Int ( _ ) ) => {
664
+ if ty:: type_is_signed ( t_1 ) { llvm:: LLVMConstFPToSI ( v, llty. to_ref ( ) ) }
643
665
else { llvm:: LLVMConstFPToUI ( v, llty. to_ref ( ) ) }
644
666
}
645
- ( expr:: cast_enum, expr:: cast_integral) => {
646
- let repr = adt:: represent_type ( cx, basety) ;
647
- let discr = adt:: const_get_discrim ( cx, & * repr, v) ;
648
- let iv = C_integral ( cx. int_type ( ) , discr, false ) ;
649
- let ety_cast = expr:: cast_type_kind ( cx. tcx ( ) , ety) ;
650
- match ety_cast {
651
- expr:: cast_integral => {
652
- let s = ty:: type_is_signed ( ety) as Bool ;
653
- llvm:: LLVMConstIntCast ( iv, llty. to_ref ( ) , s)
654
- }
655
- _ => cx. sess ( ) . bug ( "enum cast destination is not \
656
- integral")
657
- }
658
- }
659
- ( expr:: cast_pointer, expr:: cast_pointer) => {
667
+ ( CastTy :: Ptr ( _) , CastTy :: Ptr ( _) ) | ( CastTy :: FPtr , CastTy :: Ptr ( _) )
668
+ | ( CastTy :: RPtr ( _) , CastTy :: Ptr ( _) ) => {
660
669
ptrcast ( v, llty)
661
670
}
662
- ( expr:: cast_integral, expr:: cast_pointer) => {
671
+ ( CastTy :: FPtr , CastTy :: FPtr ) => ptrcast ( v, llty) , // isn't this a coercion?
672
+ ( CastTy :: Int ( _) , CastTy :: Ptr ( _) ) => {
663
673
llvm:: LLVMConstIntToPtr ( v, llty. to_ref ( ) )
664
674
}
665
- ( expr :: cast_pointer , expr :: cast_integral ) => {
675
+ ( CastTy :: Ptr ( _ ) , CastTy :: Int ( _ ) ) | ( CastTy :: FPtr , CastTy :: Int ( _ ) ) => {
666
676
llvm:: LLVMConstPtrToInt ( v, llty. to_ref ( ) )
667
677
}
668
678
_ => {
0 commit comments