From d71aec7c402ce23c15bb466965f958bae135052b Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Mon, 18 Nov 2019 12:34:55 +0300 Subject: [PATCH] Fix bug when boxing primitive value inside lambda to supertype (e.g. java.lang.Object) of corresponding wrapper type --- .../org/teavm/model/emit/ValueEmitter.java | 3 +++ .../src/test/java/org/teavm/vm/LambdaTest.java | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/core/src/main/java/org/teavm/model/emit/ValueEmitter.java b/core/src/main/java/org/teavm/model/emit/ValueEmitter.java index 4a86fe311..a4e16c315 100644 --- a/core/src/main/java/org/teavm/model/emit/ValueEmitter.java +++ b/core/src/main/java/org/teavm/model/emit/ValueEmitter.java @@ -748,6 +748,9 @@ public class ValueEmitter { if (!pe.hierarchy.isSuperType(targetClass, boxClassName, false)) { throw new EmitException("Can't convert " + this.type + " to " + targetClass); } + if (!result.type.equals(type)) { + result.type = type; + } return result; } diff --git a/tests/src/test/java/org/teavm/vm/LambdaTest.java b/tests/src/test/java/org/teavm/vm/LambdaTest.java index f8e476f76..8a40cbc10 100644 --- a/tests/src/test/java/org/teavm/vm/LambdaTest.java +++ b/tests/src/test/java/org/teavm/vm/LambdaTest.java @@ -18,6 +18,7 @@ package org.teavm.vm; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.Serializable; +import java.util.function.IntPredicate; import java.util.function.Supplier; import org.junit.Test; import org.junit.runner.RunWith; @@ -41,6 +42,23 @@ public class LambdaTest { assertTrue("Supplier is expected to implement Serializable", supplier instanceof Serializable); } + @Test + public void boxParameterToSupertype() { + assertEquals(".*.*.*.*.*", acceptIntPredicate(this::oddPredicate)); + } + + private String acceptIntPredicate(IntPredicate p) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < 10; ++i) { + sb.append(p.test(i) ? '*' : '.'); + } + return sb.toString(); + } + + private boolean oddPredicate(Object o) { + return o instanceof Integer && ((Integer) o) % 2 != 0; + } + interface A { } }