@@ -200,7 +200,7 @@ use middle::mem_categorization as mc;
200200use middle:: pat_util:: * ;
201201use trans:: adt;
202202use trans:: base:: * ;
203- use trans:: build:: { AddCase , And , BitCast , Br , CondBr , GEPi , InBoundsGEP , Load } ;
203+ use trans:: build:: { AddCase , And , Br , CondBr , GEPi , InBoundsGEP , Load , PointerCast } ;
204204use trans:: build:: { Not , Store , Sub , add_comment} ;
205205use trans:: build;
206206use trans:: callee;
@@ -853,14 +853,31 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
853853 ty:: ty_str => compare_str ( cx, lhs, rhs, rhs_t, debug_loc) ,
854854 ty:: ty_vec( ty, _) => match ty. sty {
855855 ty:: ty_uint( ast:: TyU8 ) => {
856- // NOTE: cast &[u8] to &str and abuse the str_eq lang item,
856+ // NOTE: cast &[u8] and &[u8; N] to &str and abuse the str_eq lang item,
857857 // which calls memcmp().
858- let t = ty:: mk_str_slice ( cx. tcx ( ) ,
859- cx. tcx ( ) . mk_region ( ty:: ReStatic ) ,
860- ast:: MutImmutable ) ;
861- let lhs = BitCast ( cx, lhs, type_of:: type_of ( cx. ccx ( ) , t) . ptr_to ( ) ) ;
862- let rhs = BitCast ( cx, rhs, type_of:: type_of ( cx. ccx ( ) , t) . ptr_to ( ) ) ;
863- compare_str ( cx, lhs, rhs, rhs_t, debug_loc)
858+ let pat_len = val_ty ( rhs) . element_type ( ) . array_length ( ) ;
859+ let ty_str_slice = ty:: mk_str_slice ( cx. tcx ( ) ,
860+ cx. tcx ( ) . mk_region ( ty:: ReStatic ) ,
861+ ast:: MutImmutable ) ;
862+
863+ let rhs_str = alloc_ty ( cx, ty_str_slice, "rhs_str" ) ;
864+ Store ( cx, GEPi ( cx, rhs, & [ 0 , 0 ] ) , expr:: get_dataptr ( cx, rhs_str) ) ;
865+ Store ( cx, C_uint ( cx. ccx ( ) , pat_len) , expr:: get_len ( cx, rhs_str) ) ;
866+
867+ let lhs_str;
868+ if val_ty ( lhs) == val_ty ( rhs) {
869+ // Both the discriminant and the pattern are thin pointers
870+ lhs_str = alloc_ty ( cx, ty_str_slice, "lhs_str" ) ;
871+ Store ( cx, GEPi ( cx, lhs, & [ 0 , 0 ] ) , expr:: get_dataptr ( cx, lhs_str) ) ;
872+ Store ( cx, C_uint ( cx. ccx ( ) , pat_len) , expr:: get_len ( cx, lhs_str) ) ;
873+ }
874+ else {
875+ // The discriminant is a fat pointer
876+ let llty_str_slice = type_of:: type_of ( cx. ccx ( ) , ty_str_slice) . ptr_to ( ) ;
877+ lhs_str = PointerCast ( cx, lhs, llty_str_slice) ;
878+ }
879+
880+ compare_str ( cx, lhs_str, rhs_str, rhs_t, debug_loc)
864881 } ,
865882 _ => cx. sess ( ) . bug ( "only byte strings supported in compare_values" ) ,
866883 } ,
0 commit comments