Skip to content

Commit d79be12

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

3 files changed

Lines changed: 48 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: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,7 +1351,7 @@ impl TypedAstContext {
13511351
None
13521352
}
13531353
}
1354-
CExprKind::Binary(_ty, op, lhs, rhs, _, _) => {
1354+
CExprKind::Binary(result_type_id, op, lhs, rhs, _, _) => {
13551355
let lhs_type_id =
13561356
self.ast_context.c_exprs[&lhs].kind.get_qual_type().unwrap();
13571357
let rhs_type_id =
@@ -1365,11 +1365,26 @@ impl TypedAstContext {
13651365
}
13661366

13671367
if op.all_types_same() {
1368-
if CTypeKind::PULLBACK_KINDS.contains(lhs_type_kind) {
1369-
Some(lhs_type_id)
1370-
} else {
1371-
Some(rhs_type_id)
1368+
let result_type_kind =
1369+
&self.ast_context.resolve_type(result_type_id.ctype).kind;
1370+
1371+
let mut result_type_id =
1372+
if CTypeKind::PULLBACK_KINDS.contains(lhs_type_kind) {
1373+
lhs_type_id
1374+
} else {
1375+
rhs_type_id
1376+
};
1377+
1378+
// For complex arithmetic, complex and real values can be mixed.
1379+
// See if a `Complex` version of the new result type exists.
1380+
if matches!(result_type_kind, CTypeKind::Complex(..)) {
1381+
let new_result_type_kind = CTypeKind::Complex(result_type_id.ctype);
1382+
let new_type_id =
1383+
self.ast_context.type_for_kind(&new_result_type_kind);
1384+
result_type_id.ctype = new_type_id;
13721385
}
1386+
1387+
Some(result_type_id)
13731388
} else if op.is_bitshift() {
13741389
Some(lhs_type_id)
13751390
} else {

c2rust-transpile/src/translator/operators.rs

Lines changed: 22 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
@@ -284,7 +297,15 @@ impl<'c> Translation<'c> {
284297
{
285298
// If the rhs must match the lhs but doesn't, add a cast.
286299
// 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);
300+
let mut target_type_id = compute_lhs_type_id.unwrap_or(lhs_type_id);
301+
302+
// For complex arithmetic, complex and real values can be mixed.
303+
if let &CTypeKind::Complex(lhs_scalar_type_id) = lhs_type_kind {
304+
if !matches!(rhs_type_kind, CTypeKind::Complex(..)) {
305+
target_type_id.ctype = lhs_scalar_type_id;
306+
}
307+
}
308+
288309
rhs_rs = self.make_cast(ctx.used(), rhs_type_id, target_type_id, rhs_rs)?;
289310
}
290311
}

0 commit comments

Comments
 (0)