Skip to content

Commit 74e957f

Browse files
authored
Improve changetype check (#898)
1 parent 6c0041e commit 74e957f

File tree

2 files changed

+11
-2
lines changed

2 files changed

+11
-2
lines changed

src/builtins.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2037,10 +2037,10 @@ export function compileCall(
20372037
checkArgsRequired(operands, 1, reportNode, compiler)
20382038
) return module.unreachable();
20392039
let toType = typeArguments![0];
2040-
let arg0 = compiler.compileExpression(operands[0], toType);
2040+
let arg0 = compiler.compileExpression(operands[0], Type.auto);
20412041
let fromType = compiler.currentType;
20422042
compiler.currentType = toType;
2043-
if (fromType.size != toType.size) {
2043+
if (!fromType.isChangeableTo(toType)) {
20442044
compiler.error(
20452045
DiagnosticCode.Type_0_cannot_be_changed_to_type_1,
20462046
reportNode.range, fromType.toString(), toType.toString()

src/types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,15 @@ export class Type {
280280
return this.kind == target.kind;
281281
}
282282

283+
/** Tests if a value of this type can be changed to the target type using `changetype`. */
284+
isChangeableTo(target: Type): bool {
285+
if (this.is(TypeFlags.INTEGER) && target.is(TypeFlags.INTEGER)) {
286+
let size = this.size;
287+
return size == target.size && (size >= 32 || this.is(TypeFlags.SIGNED) == target.is(TypeFlags.SIGNED));
288+
}
289+
return this.kind == target.kind;
290+
}
291+
283292
/** Determines the common denominator type of two types, if there is any. */
284293
static commonDenominator(left: Type, right: Type, signednessIsImportant: bool): Type | null {
285294
if (right.isAssignableTo(left, signednessIsImportant)) return left;

0 commit comments

Comments
 (0)