Skip to content

Commit d998303

Browse files
committed
transpile: Refactor operand type selection in operators.rs and bubble_expr_types
1 parent cf72d63 commit d998303

2 files changed

Lines changed: 48 additions & 57 deletions

File tree

c2rust-transpile/src/c_ast/mod.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,31 +1340,32 @@ impl TypedAstContext {
13401340
let rhs_type_id =
13411341
self.ast_context.c_exprs[&rhs].kind.get_qual_type().unwrap();
13421342

1343-
let lhs_resolved_ty = self.ast_context.resolve_type(lhs_type_id.ctype);
1344-
let rhs_resolved_ty = self.ast_context.resolve_type(rhs_type_id.ctype);
1343+
let lhs_type_kind = &self.ast_context.resolve_type(lhs_type_id.ctype).kind;
1344+
let rhs_type_kind = &self.ast_context.resolve_type(rhs_type_id.ctype).kind;
13451345

1346-
if CTypeKind::PULLBACK_KINDS.contains(&lhs_resolved_ty.kind) {
1346+
if CTypeKind::PULLBACK_KINDS.contains(lhs_type_kind) {
13471347
Some(lhs_type_id)
1348-
} else if CTypeKind::PULLBACK_KINDS.contains(&rhs_resolved_ty.kind) {
1348+
} else if CTypeKind::PULLBACK_KINDS.contains(rhs_type_kind) {
13491349
Some(rhs_type_id)
13501350
} else {
13511351
None
13521352
}
13531353
}
13541354
CExprKind::Binary(_ty, op, lhs, rhs, _, _) => {
1355+
let lhs_type_id =
1356+
self.ast_context.c_exprs[&lhs].kind.get_qual_type().unwrap();
13551357
let rhs_type_id =
13561358
self.ast_context.c_exprs[&rhs].kind.get_qual_type().unwrap();
1357-
let lhs_kind = &self.ast_context.c_exprs[&lhs].kind;
1358-
let lhs_type_id = lhs_kind.get_qual_type().unwrap();
13591359

1360-
let lhs_resolved_ty = self.ast_context.resolve_type(lhs_type_id.ctype);
1361-
let rhs_resolved_ty = self.ast_context.resolve_type(rhs_type_id.ctype);
1360+
let lhs_type_kind = &self.ast_context.resolve_type(lhs_type_id.ctype).kind;
1361+
let rhs_type_kind = &self.ast_context.resolve_type(rhs_type_id.ctype).kind;
13621362

1363-
let neither_ptr = !lhs_resolved_ty.kind.is_pointer()
1364-
&& !rhs_resolved_ty.kind.is_pointer();
1363+
if lhs_type_kind.is_pointer() || rhs_type_kind.is_pointer() {
1364+
return;
1365+
}
13651366

1366-
if op.all_types_same() && neither_ptr {
1367-
if CTypeKind::PULLBACK_KINDS.contains(&lhs_resolved_ty.kind) {
1367+
if op.all_types_same() {
1368+
if CTypeKind::PULLBACK_KINDS.contains(lhs_type_kind) {
13681369
Some(lhs_type_id)
13691370
} else {
13701371
Some(rhs_type_id)

c2rust-transpile/src/translator/operators.rs

Lines changed: 35 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)