Skip to content

Commit e62b79c

Browse files
committed
transpile: Special case mixed operand types for complex arithmetic
1 parent ee67763 commit e62b79c

3 files changed

Lines changed: 49 additions & 6 deletions

File tree

c2rust-transpile/src/c_ast/conversion.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,12 @@ impl ConversionContext {
472472
self.add_type(new_id, not_located(rust_type_kind));
473473
self.processed_nodes
474474
.insert(new_id, self::node_types::OTHER_TYPE);
475+
476+
let complex_kind = CTypeKind::Complex(CTypeId(new_id));
477+
let new_id = self.id_mapper.fresh_id();
478+
self.add_type(new_id, not_located(complex_kind));
479+
self.processed_nodes
480+
.insert(new_id, self::node_types::OTHER_TYPE);
475481
}
476482

477483
// Continue popping Clang nodes off of the stack of nodes we have promised to visit

c2rust-transpile/src/c_ast/mod.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,7 +1347,7 @@ impl TypedAstContext {
13471347
None
13481348
}
13491349
}
1350-
CExprKind::Binary(_ty, op, lhs, rhs, _, _) => {
1350+
CExprKind::Binary(result_type_id, op, lhs, rhs, _, _) => {
13511351
let lhs_type_id =
13521352
self.ast_context.c_exprs[&lhs].kind.get_qual_type().unwrap();
13531353
let rhs_type_id =
@@ -1361,11 +1361,28 @@ impl TypedAstContext {
13611361
}
13621362

13631363
if op.all_types_same() {
1364-
if CTypeKind::PULLBACK_KINDS.contains(lhs_type_kind) {
1365-
Some(lhs_type_id)
1366-
} else {
1367-
Some(rhs_type_id)
1364+
let result_type_kind =
1365+
&self.ast_context.resolve_type(result_type_id.ctype).kind;
1366+
1367+
let mut result_type_id =
1368+
if CTypeKind::PULLBACK_KINDS.contains(lhs_type_kind) {
1369+
lhs_type_id
1370+
} else {
1371+
rhs_type_id
1372+
};
1373+
1374+
// For complex arithmetic, complex and real values can be mixed.
1375+
// See if a `Complex` version of the new result type exists.
1376+
if matches!(result_type_kind, CTypeKind::Complex(..)) {
1377+
let new_result_type_kind = CTypeKind::Complex(result_type_id.ctype);
1378+
let new_type_id = self
1379+
.ast_context
1380+
.type_for_kind(&new_result_type_kind)
1381+
.unwrap();
1382+
result_type_id.ctype = new_type_id;
13681383
}
1384+
1385+
Some(result_type_id)
13691386
} else if op.is_bitshift() {
13701387
Some(lhs_type_id)
13711388
} else {

c2rust-transpile/src/translator/operators.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,19 @@ impl<'c> Translation<'c> {
9797
// Ops like division and bitxor accept inputs of their expected result type.
9898
lhs_type_id.ctype = expr_type_id.ctype;
9999
rhs_type_id.ctype = expr_type_id.ctype;
100+
101+
// For complex arithmetic, complex and real values can be mixed.
102+
let expr_type_kind =
103+
&self.ast_context.resolve_type(expr_type_id.ctype).kind;
104+
if let &CTypeKind::Complex(result_scalar_type_id) = expr_type_kind {
105+
if !matches!(lhs_type_kind, CTypeKind::Complex(..)) {
106+
lhs_type_id.ctype = result_scalar_type_id;
107+
}
108+
109+
if !matches!(rhs_type_kind, CTypeKind::Complex(..)) {
110+
rhs_type_id.ctype = result_scalar_type_id;
111+
}
112+
}
100113
} else if op.input_types_same() && lhs_type_kind != rhs_type_kind {
101114
// Ops like comparisons require argument types to match, but the result type
102115
// doesn't inform us what type to choose. Select a synthetic definition of a
@@ -288,7 +301,14 @@ impl<'c> Translation<'c> {
288301
{
289302
// If the rhs must match the lhs but doesn't, add a cast.
290303
// 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);
304+
let mut target_type_id = compute_lhs_type_id.unwrap_or(lhs_type_id);
305+
306+
// For complex arithmetic, complex and real values can be mixed.
307+
if let &CTypeKind::Complex(lhs_scalar_type_id) = lhs_type_kind {
308+
if !matches!(rhs_type_kind, CTypeKind::Complex(..)) {
309+
target_type_id.ctype = lhs_scalar_type_id;
310+
}
311+
}
292312

293313
rhs_rs = self.convert_cast(
294314
ctx.used(),

0 commit comments

Comments
 (0)