@@ -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,61 @@ 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
+ if expr:: cast_is_noop ( t_e, t_1) {
622
624
return v;
623
625
}
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 ;
626
+ if type_is_fat_ptr ( cx. tcx ( ) , t_e) {
627
+ // Fat pointer casts.
628
+ let t_1_inner = ty:: deref ( t_1, true ) . expect ( "cast to non-pointer" ) . ty ;
629
+ let ptr_ty = type_of:: in_memory_type_of ( cx, t_1_inner) . ptr_to ( ) ;
630
+ let addr = ptrcast ( const_get_elt ( cx, v, & [ abi:: FAT_PTR_ADDR as u32 ] ) ,
631
+ ptr_ty) ;
632
+ if type_is_fat_ptr ( cx. tcx ( ) , t_1) {
633
+ let info = const_get_elt ( cx, v, & [ abi:: FAT_PTR_EXTRA as u32 ] ) ;
634
+ return C_struct ( cx, & [ addr, info] , false )
635
+ } else {
636
+ return addr;
637
+ }
638
+ }
639
+ match ( CastTy :: recognize ( cx. tcx ( ) , t_e) . expect ( "bad input type for cast" ) ,
640
+ CastTy :: recognize ( cx. tcx ( ) , t_1) . expect ( "bad output type for cast" ) ) {
641
+ ( CastTy :: Int ( IntTy :: CEnum ) , CastTy :: Int ( _) ) => {
642
+ let repr = adt:: represent_type ( cx, t_e) ;
643
+ let discr = adt:: const_get_discrim ( cx, & * repr, v) ;
644
+ let iv = C_integral ( cx. int_type ( ) , discr, false ) ;
645
+ let s = ty:: type_is_signed ( t_1) as Bool ;
646
+ llvm:: LLVMConstIntCast ( iv, llty. to_ref ( ) , s)
647
+ }
648
+ ( CastTy :: Int ( _) , CastTy :: Int ( _) ) => {
649
+ let s = ty:: type_is_signed ( t_1) as Bool ;
629
650
llvm:: LLVMConstIntCast ( v, llty. to_ref ( ) , s)
630
651
}
631
- ( expr :: cast_integral , expr :: cast_float ) => {
632
- if ty:: type_is_signed ( basety ) {
652
+ ( CastTy :: Int ( _ ) , CastTy :: Float ) => {
653
+ if ty:: type_is_signed ( t_1 ) {
633
654
llvm:: LLVMConstSIToFP ( v, llty. to_ref ( ) )
634
655
} else {
635
656
llvm:: LLVMConstUIToFP ( v, llty. to_ref ( ) )
636
657
}
637
658
}
638
- ( expr :: cast_float , expr :: cast_float ) => {
659
+ ( CastTy :: Float , CastTy :: Float ) => {
639
660
llvm:: LLVMConstFPCast ( v, llty. to_ref ( ) )
640
661
}
641
- ( expr :: cast_float , expr :: cast_integral ) => {
642
- if ty:: type_is_signed ( ety ) { llvm:: LLVMConstFPToSI ( v, llty. to_ref ( ) ) }
662
+ ( CastTy :: Float , CastTy :: Int ( _ ) ) => {
663
+ if ty:: type_is_signed ( t_1 ) { llvm:: LLVMConstFPToSI ( v, llty. to_ref ( ) ) }
643
664
else { llvm:: LLVMConstFPToUI ( v, llty. to_ref ( ) ) }
644
665
}
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) => {
666
+ ( CastTy :: Ptr ( _) , CastTy :: Ptr ( _) ) | ( CastTy :: FPtr , CastTy :: Ptr ( _) )
667
+ | ( CastTy :: RPtr ( _) , CastTy :: Ptr ( _) ) => {
660
668
ptrcast ( v, llty)
661
669
}
662
- ( expr:: cast_integral, expr:: cast_pointer) => {
670
+ ( CastTy :: FPtr , CastTy :: FPtr ) => ptrcast ( v, llty) , // isn't this a coercion?
671
+ ( CastTy :: Int ( _) , CastTy :: Ptr ( _) ) => {
663
672
llvm:: LLVMConstIntToPtr ( v, llty. to_ref ( ) )
664
673
}
665
- ( expr :: cast_pointer , expr :: cast_integral ) => {
674
+ ( CastTy :: Ptr ( _ ) , CastTy :: Int ( _ ) ) | ( CastTy :: FPtr , CastTy :: Int ( _ ) ) => {
666
675
llvm:: LLVMConstPtrToInt ( v, llty. to_ref ( ) )
667
676
}
668
677
_ => {
0 commit comments