Skip to content

Commit 510b152

Browse files
committed
Fix erased operands in Lua composite expressions
1 parent 5c72fae commit 510b152

2 files changed

Lines changed: 32 additions & 4 deletions

File tree

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/translation/imtranslation/ExprTranslation.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,14 @@ public static ImExpr translateIntern(ExprBinary e, ImTranslator t, ImFunction f)
212212
FuncLink overloadedOperator = e.attrFuncLink();
213213
ImExpr left = translateConcatOperand(e, e.getLeft(), t, f, overloadedOperator);
214214
ImExpr right = translateConcatOperand(e, e.getRight(), t, f, overloadedOperator);
215+
if (overloadedOperator == null) {
216+
// A built-in operator can leave both operands with the same erased
217+
// generic type. In that case there is no concrete expected type to
218+
// trigger wrapTranslation, but Lua still needs each operand's
219+
// primitive default restored before applying the operator.
220+
left = normalizeBuiltinOperand(e.getLeft(), left, t);
221+
right = normalizeBuiltinOperand(e.getRight(), right, t);
222+
}
215223
if (op == WurstOperator.PLUS && overloadedOperator == null) {
216224
left = wrapImplicitToString(e, e.getLeft(), left, t);
217225
right = wrapImplicitToString(e, e.getRight(), right, t);
@@ -243,6 +251,14 @@ public static ImExpr translateIntern(ExprBinary e, ImTranslator t, ImFunction f)
243251
return ImOperatorCall(op, ImExprs(left, right));
244252
}
245253

254+
private static ImExpr normalizeBuiltinOperand(Expr operand, ImExpr translated, ImTranslator t) {
255+
if (!t.isLuaTarget() || !(operand.attrTypRaw() instanceof WurstTypeBoundTypeParam)
256+
|| isAlreadyTypeAssured(translated, t)) {
257+
return translated;
258+
}
259+
return wrapLua(operand, t, translated, operand.attrTypRaw());
260+
}
261+
246262
private static ImExpr translateConcatOperand(ExprBinary concat, Expr operand, ImTranslator t, ImFunction f,
247263
@Nullable FuncLink overloadedOperator) {
248264
if (concat.getOp() == WurstOperator.PLUS && overloadedOperator == null
@@ -926,7 +942,9 @@ public static ImExpr translateIntern(ExprNewObject e, ImTranslator t, ImFunction
926942
WurstTypeClass wurstType = (WurstTypeClass) e.attrTyp();
927943
ImClass imClass = t.getClassFor(wurstType.getClassDef());
928944
ImTypeArguments typeArgs = getFunctionCallTypeArguments(t, sig, e, imClass.getTypeVariables());
929-
return ImFunctionCall(e, constructorImFunc, typeArgs, translateExprs(e.getArgs(), t, f), false, CallType.NORMAL);
945+
FunctionSignature selectedSignature = t.isLuaTarget() ? sig : null;
946+
return ImFunctionCall(e, constructorImFunc, typeArgs,
947+
translateExprs(e.getArgs(), t, f, false, selectedSignature), false, CallType.NORMAL);
930948
}
931949

932950
public static ImExprOpt translate(NoExpr e, ImTranslator translator, ImFunction f) {

de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/LuaBackendAuditTests.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2327,6 +2327,14 @@ public void erasedGenericPrimitiveDefaultsPropagateThroughCompositeContexts() th
23272327
"class Addable",
23282328
" function op_plus(int value) returns int",
23292329
" return value",
2330+
"class Constructed",
2331+
" int value",
2332+
" construct(int value)",
2333+
" this.value = value",
2334+
" construct(string value)",
2335+
" this.value = -1",
2336+
" function get() returns int",
2337+
" return value",
23302338
"function consume(int value) returns int",
23312339
" return value",
23322340
"function consume(string value) returns int",
@@ -2340,24 +2348,26 @@ public void erasedGenericPrimitiveDefaultsPropagateThroughCompositeContexts() th
23402348
" bool useBox = true",
23412349
" values[0] = 7",
23422350
" let sum = addable + box.get()",
2351+
" let builtinSum = box.get() + box.get()",
23432352
" let overloaded = consume(useBox ? box.get() : 0)",
23442353
" let indexed = values[useBox ? box.get() : 0]",
23452354
" IntSupplier supplier = () -> (useBox ? box.get() : 0)",
23462355
" IntSupplier unarySupplier = () -> -box.get()",
2356+
" let constructed = new Constructed(useBox ? box.get() : 0)",
23472357
" int blockValue = begin",
23482358
" return (useBox ? box.get() : 0)",
23492359
" end",
23502360
" int switchValue = -1",
23512361
" switch (useBox ? box.get() : 1)",
23522362
" case 0",
23532363
" switchValue = 0",
2354-
" if sum == 0 and overloaded == 0 and indexed == 7 and supplier.get() == 0",
2364+
" if sum == 0 and builtinSum == 0 and overloaded == 0 and indexed == 7 and supplier.get() == 0",
23552365
" and unarySupplier.get() == 0",
2356-
" and blockValue == 0 and switchValue == 0",
2366+
" and blockValue == 0 and switchValue == 0 and constructed.get() == 0",
23572367
" testSuccess()"
23582368
);
23592369
String compiled = compiledLua("erasedGenericPrimitiveDefaultsPropagateThroughCompositeContexts");
2360-
assertEquals("each concrete integer consumer must normalize its erased generic input", 7,
2370+
assertEquals("each concrete integer consumer must normalize its erased generic input", 10,
23612371
countOccurrences(compiled, "__wurst_ensureInt(Box_Box_get("));
23622372
}
23632373

0 commit comments

Comments
 (0)