@@ -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
@@ -271,31 +267,25 @@ impl<'c> Translation<'c> {
271267 . get_qual_type ( )
272268 . ok_or_else ( || format_err ! ( "bad initial lhs type" ) ) ?;
273269
274- // First, translate the rhs. Then, if it must match the lhs but doesn't, add a cast.
275- let mut rhs_translation = self . convert_expr ( ctx. used ( ) , rhs, Some ( rhs_type_id) ) ?;
276- let lhs_rhs_types_must_match = {
277- let lhs_resolved_ty = & self . ast_context . resolve_type ( lhs_type_id. ctype ) ;
278- let rhs_resolved_ty = & self . ast_context . resolve_type ( rhs_type_id. ctype ) ;
279- // Addition and subtraction can accept one pointer argument for .offset(), in which
280- // case we don't want to homogenize arg types.
281- let neither_ptr =
282- !lhs_resolved_ty. kind . is_pointer ( ) && !rhs_resolved_ty. kind . is_pointer ( ) ;
283-
284- op. underlying_assignment ( ) . map_or ( true , |op| {
285- if op. is_pointer_arithmetic ( ) {
286- neither_ptr
287- } else {
288- op. is_arithmetic ( ) || op. is_bitwise ( )
289- }
290- } )
291- } ;
292- if lhs_rhs_types_must_match {
293- // For compound assignment, use the compute type; for regular assignment, use lhs type
294- let effective_lhs_ty = compute_lhs_type_id. unwrap_or ( lhs_type_id) ;
295- if effective_lhs_ty. ctype != rhs_type_id. ctype {
296- let new_rhs_ty =
297- self . convert_type ( compute_lhs_type_id. unwrap_or ( lhs_type_id) . ctype ) ?;
298- rhs_translation = rhs_translation. map ( |val| mk ( ) . cast_expr ( val, new_rhs_ty) ) ;
270+ // First, translate the rhs.
271+ let mut rhs_rs = self . convert_expr ( ctx. used ( ) , rhs, Some ( rhs_type_id) ) ?;
272+
273+ let lhs_type_kind = & self . ast_context . resolve_type ( lhs_type_id. ctype ) . kind ;
274+ let rhs_type_kind = & self . ast_context . resolve_type ( rhs_type_id. ctype ) . kind ;
275+
276+ // Addition and subtraction can accept one pointer argument for .offset(), in which
277+ // case we don't want to homogenize arg types.
278+ if !( op. is_pointer_arithmetic ( )
279+ && ( lhs_type_kind. is_pointer ( ) || rhs_type_kind. is_pointer ( ) ) )
280+ {
281+ if op
282+ . underlying_assignment ( )
283+ . map_or ( true , |op| op. is_arithmetic ( ) || op. is_bitwise ( ) )
284+ {
285+ // If the rhs must match the lhs but doesn't, add a cast.
286+ // For compound assignment, use the compute type; for regular assignment, use lhs type.
287+ let target_type_id = compute_lhs_type_id. unwrap_or ( lhs_type_id) ;
288+ rhs_rs = self . make_cast ( ctx. used ( ) , rhs_type_id, target_type_id, rhs_rs) ?;
299289 }
300290 }
301291
@@ -306,7 +296,7 @@ impl<'c> Translation<'c> {
306296 expr_type_id,
307297 lhs,
308298 rhs_type_id,
309- rhs_translation ,
299+ rhs_rs ,
310300 compute_lhs_type_id,
311301 compute_res_type_id,
312302 )
0 commit comments