@@ -85,38 +85,34 @@ impl<'c> Translation<'c> {
8585
8686 // If this operation will (in Rust) take args of the same type, then propagate our
8787 // expected type down to the translation of our argument expressions.
88- let lhs_resolved_ty = self . ast_context . resolve_type ( lhs_type_id. ctype ) ;
89- let rhs_resolved_ty = self . ast_context . resolve_type ( rhs_type_id. ctype ) ;
90- let expr_ty_kind = & self . ast_context . index ( expr_type_id . ctype ) . kind ;
88+ let lhs_type_kind = & self . ast_context . resolve_type ( lhs_type_id. ctype ) . kind ;
89+ let rhs_type_kind = & self . ast_context . resolve_type ( rhs_type_id. ctype ) . kind ;
90+
9191 // Addition and subtraction can accept one pointer argument for .offset(), in which
9292 // case we don't want to homogenize arg types.
93- if !lhs_resolved_ty. kind . is_pointer ( )
94- && !rhs_resolved_ty. kind . is_pointer ( )
95- && !expr_ty_kind. is_pointer ( )
93+ if !( op. is_pointer_arithmetic ( )
94+ && ( lhs_type_kind. is_pointer ( ) || rhs_type_kind. is_pointer ( ) ) )
9695 {
9796 if op. all_types_same ( ) {
9897 // Ops like division and bitxor accept inputs of their expected result type.
99- lhs_type_id = expr_type_id;
100- rhs_type_id = expr_type_id;
101- } else if op. input_types_same ( ) && lhs_resolved_ty. kind != rhs_resolved_ty. kind
102- {
98+ lhs_type_id. ctype = expr_type_id. ctype ;
99+ rhs_type_id. ctype = expr_type_id. ctype ;
100+ } else if op. input_types_same ( ) && lhs_type_kind != rhs_type_kind {
103101 // Ops like comparisons require argument types to match, but the result type
104102 // doesn't inform us what type to choose. Select a synthetic definition of a
105103 // portable rust type (e.g. u64 or usize) if either arg is one.
106104 trace ! (
107105 "Binary op arg types differ: {:?} vs {:?}" ,
108- lhs_resolved_ty . kind ,
109- rhs_resolved_ty . kind
106+ lhs_type_kind ,
107+ rhs_type_kind
110108 ) ;
111- let ty = if CTypeKind :: PULLBACK_KINDS . contains ( & lhs_resolved_ty . kind ) {
112- lhs_type_id
109+ if CTypeKind :: PULLBACK_KINDS . contains ( & lhs_type_kind ) {
110+ rhs_type_id . ctype = lhs_type_id. ctype ;
113111 } else {
114- rhs_type_id
112+ lhs_type_id . ctype = rhs_type_id. ctype ;
115113 } ;
116- lhs_type_id = ty;
117- rhs_type_id = ty;
118- } else if matches ! ( op, ShiftLeft | ShiftRight ) {
119- lhs_type_id = expr_type_id;
114+ } else if op. is_bitshift ( ) {
115+ lhs_type_id. ctype = expr_type_id. ctype ;
120116 }
121117 }
122118
@@ -275,31 +271,34 @@ impl<'c> Translation<'c> {
275271 . get_qual_type ( )
276272 . ok_or_else ( || format_err ! ( "bad initial lhs type" ) ) ?;
277273
278- // First, translate the rhs. Then, if it must match the lhs but doesn't, add a cast.
279- let mut rhs_translation = self . convert_expr ( ctx. used ( ) , rhs, Some ( rhs_type_id) ) ?;
280- let lhs_rhs_types_must_match = {
281- let lhs_resolved_ty = & self . ast_context . resolve_type ( lhs_type_id. ctype ) ;
282- let rhs_resolved_ty = & self . ast_context . resolve_type ( rhs_type_id. ctype ) ;
283- // Addition and subtraction can accept one pointer argument for .offset(), in which
284- // case we don't want to homogenize arg types.
285- let neither_ptr =
286- !lhs_resolved_ty. kind . is_pointer ( ) && !rhs_resolved_ty. kind . is_pointer ( ) ;
287-
288- op. underlying_assignment ( ) . map_or ( true , |op| {
289- if op. is_pointer_arithmetic ( ) {
290- neither_ptr
291- } else {
292- op. is_arithmetic ( ) || op. is_bitwise ( )
293- }
294- } )
295- } ;
296- if lhs_rhs_types_must_match {
297- // For compound assignment, use the compute type; for regular assignment, use lhs type
298- let effective_lhs_ty = compute_lhs_type_id. unwrap_or ( lhs_type_id) ;
299- if effective_lhs_ty. ctype != rhs_type_id. ctype {
300- let new_rhs_ty =
301- self . convert_type ( compute_lhs_type_id. unwrap_or ( lhs_type_id) . ctype ) ?;
302- rhs_translation = rhs_translation. map ( |val| mk ( ) . cast_expr ( val, new_rhs_ty) ) ;
274+ // First, translate the rhs.
275+ let mut rhs_rs = self . convert_expr ( ctx. used ( ) , rhs, Some ( rhs_type_id) ) ?;
276+
277+ let lhs_type_kind = & self . ast_context . resolve_type ( lhs_type_id. ctype ) . kind ;
278+ let rhs_type_kind = & self . ast_context . resolve_type ( rhs_type_id. ctype ) . kind ;
279+
280+ // Addition and subtraction can accept one pointer argument for .offset(), in which
281+ // case we don't want to homogenize arg types.
282+ if !( op. is_pointer_arithmetic ( )
283+ && ( lhs_type_kind. is_pointer ( ) || rhs_type_kind. is_pointer ( ) ) )
284+ {
285+ if op
286+ . underlying_assignment ( )
287+ . map_or ( true , |op| op. is_arithmetic ( ) || op. is_bitwise ( ) )
288+ {
289+ // If the rhs must match the lhs but doesn't, add a cast.
290+ // For compound assignment, use the compute type; for regular assignment, use lhs type.
291+ let target_type_id = compute_lhs_type_id. unwrap_or ( lhs_type_id) ;
292+
293+ rhs_rs = self . convert_cast (
294+ ctx. used ( ) ,
295+ rhs_type_id,
296+ target_type_id,
297+ rhs_rs,
298+ None ,
299+ None ,
300+ None ,
301+ ) ?;
303302 }
304303 }
305304
@@ -310,7 +309,7 @@ impl<'c> Translation<'c> {
310309 expr_type_id,
311310 lhs,
312311 rhs_type_id,
313- rhs_translation ,
312+ rhs_rs ,
314313 compute_lhs_type_id,
315314 compute_res_type_id,
316315 )
0 commit comments