@@ -29,6 +29,7 @@ use trans::declare;
2929use trans:: monomorphize;
3030use trans:: type_:: Type ;
3131use trans:: type_of;
32+ use middle:: cast:: { CastTy , IntTy } ;
3233use middle:: subst:: Substs ;
3334use middle:: ty:: { self , Ty } ;
3435use util:: ppaux:: { Repr , ty_to_string} ;
@@ -616,53 +617,62 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
616617 }
617618 }
618619 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) {
622625 return v;
623626 }
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 ;
629651 llvm:: LLVMConstIntCast ( v, llty. to_ref ( ) , s)
630652 }
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 ) {
633655 llvm:: LLVMConstSIToFP ( v, llty. to_ref ( ) )
634656 } else {
635657 llvm:: LLVMConstUIToFP ( v, llty. to_ref ( ) )
636658 }
637659 }
638- ( expr :: cast_float , expr :: cast_float ) => {
660+ ( CastTy :: Float , CastTy :: Float ) => {
639661 llvm:: LLVMConstFPCast ( v, llty. to_ref ( ) )
640662 }
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 ( ) ) }
643665 else { llvm:: LLVMConstFPToUI ( v, llty. to_ref ( ) ) }
644666 }
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 ( _) ) => {
660669 ptrcast ( v, llty)
661670 }
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 ( _) ) => {
663673 llvm:: LLVMConstIntToPtr ( v, llty. to_ref ( ) )
664674 }
665- ( expr :: cast_pointer , expr :: cast_integral ) => {
675+ ( CastTy :: Ptr ( _ ) , CastTy :: Int ( _ ) ) | ( CastTy :: FPtr , CastTy :: Int ( _ ) ) => {
666676 llvm:: LLVMConstPtrToInt ( v, llty. to_ref ( ) )
667677 }
668678 _ => {
0 commit comments