Merge "Support for Object -> boxed type -> primitive type adjustment for method references."
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaMainMethodSourceCode.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaMainMethodSourceCode.java
index bfaee32..a4de54f 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaMainMethodSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaMainMethodSourceCode.java
@@ -134,6 +134,11 @@
}
if (b.isPrimitiveType()) {
+ if (a == factory.objectType) {
+ // `a` is java.lang.Object in which case we assume it represented by
+ // proper boxed type.
+ return true;
+ }
// `a` is a boxed type for `a*` which can be
// widened to primitive type `b`.
DexType unboxedA = getPrimitiveFromBoxed(a);
@@ -313,9 +318,16 @@
// type, the value must be unboxed and converted to the resulting type via primitive
// widening conversion.
if (toTypePrimitive) {
- DexType fromTypeAsPrimitive = getPrimitiveFromBoxed(fromType);
+ DexType boxedType = fromType;
+ if (boxedType == factory().objectType) {
+ // We are in situation when from(=java.lang.Object) is being adjusted to a
+ // primitive type, in which case we assume it is of proper box type.
+ boxedType = getBoxedForPrimitiveType(toType);
+ register = castToBoxedType(register, boxedType);
+ }
+ DexType fromTypeAsPrimitive = getPrimitiveFromBoxed(boxedType);
if (fromTypeAsPrimitive != null) {
- int unboxedRegister = addPrimitiveUnboxing(register, fromTypeAsPrimitive, fromType);
+ int unboxedRegister = addPrimitiveUnboxing(register, fromTypeAsPrimitive, boxedType);
return addPrimitiveWideningConversion(unboxedRegister, fromTypeAsPrimitive, toType);
}
}
@@ -461,6 +473,11 @@
return result;
}
+ private int castToBoxedType(int register, DexType boxType) {
+ add(builder -> builder.addCheckCast(register, boxType));
+ return register;
+ }
+
private int addPrimitiveBoxing(int register, DexType primitiveType, DexType boxType) {
// Generate factory method fo boxing.
DexItemFactory factory = factory();
diff --git a/src/test/examplesAndroidO/lambdadesugaring/ValueAdjustments.java b/src/test/examplesAndroidO/lambdadesugaring/ValueAdjustments.java
index b9d2752..18f8d64 100644
--- a/src/test/examplesAndroidO/lambdadesugaring/ValueAdjustments.java
+++ b/src/test/examplesAndroidO/lambdadesugaring/ValueAdjustments.java
@@ -13,6 +13,10 @@
int i, Integer I, long l, Long L, float f, Float F, double d, Double D);
}
+ interface it<T> {
+ T t();
+ }
+
interface iz {
boolean f();
}
@@ -135,6 +139,11 @@
private static void checkDouble(StringBuffer builder) {
builder
+ .append(((id) new it<Double>() {
+ @Override public Double t() {
+ return (double) (Integer.MAX_VALUE) + 1;
+ }
+ }::t).f()).append(' ')
.append(((id) ValueAdjustments::b).f()).append(' ')
.append(((id) ValueAdjustments::B).f()).append(' ')
.append(((id) ValueAdjustments::s).f()).append(' ')
@@ -153,6 +162,11 @@
private static void checkFloat(StringBuffer builder) {
builder
+ .append(((if_) new it<Float>() {
+ @Override public Float t() {
+ return (float) (Short.MAX_VALUE) + 1;
+ }
+ }::t).f()).append(' ')
.append(((if_) ValueAdjustments::b).f()).append(' ')
.append(((if_) ValueAdjustments::B).f()).append(' ')
.append(((if_) ValueAdjustments::s).f()).append(' ')
@@ -169,6 +183,11 @@
private static void checkLong(StringBuffer builder) {
builder
+ .append(((ij) new it<Long>() {
+ @Override public Long t() {
+ return (long) (Integer.MAX_VALUE) + 1;
+ }
+ }::t).f()).append(' ')
.append(((ij) ValueAdjustments::b).f()).append(' ')
.append(((ij) ValueAdjustments::B).f()).append(' ')
.append(((ij) ValueAdjustments::s).f()).append(' ')
@@ -183,6 +202,11 @@
private static void checkInt(StringBuffer builder) {
builder
+ .append(((ii) new it<Integer>() {
+ @Override public Integer t() {
+ return Short.MAX_VALUE + 1;
+ }
+ }::t).f()).append(' ')
.append(((ii) ValueAdjustments::b).f()).append(' ')
.append(((ii) ValueAdjustments::B).f()).append(' ')
.append(((ii) ValueAdjustments::s).f()).append(' ')
@@ -195,6 +219,11 @@
private static void checkShort(StringBuffer builder) {
builder
+ .append(((is) new it<Short>() {
+ @Override public Short t() {
+ return 256;
+ }
+ }::t).f()).append(' ')
.append(((is) ValueAdjustments::b).f()).append(' ')
.append(((is) ValueAdjustments::B).f()).append(' ')
.append(((is) ValueAdjustments::s).f()).append(' ')
@@ -203,18 +232,33 @@
private static void checkChar(StringBuffer builder) {
builder
+ .append(((ic) new it<Character>() {
+ @Override public Character t() {
+ return 'C';
+ }
+ }::t).f()).append(' ')
.append(((ic) ValueAdjustments::c).f()).append(' ')
.append(((ic) ValueAdjustments::C).f()).append('\n');
}
private static void checkByte(StringBuffer builder) {
builder
+ .append(((ib) new it<Byte>() {
+ @Override public Byte t() {
+ return 11;
+ }
+ }::t).f()).append(' ')
.append(((ib) ValueAdjustments::b).f()).append(' ')
.append(((ib) ValueAdjustments::B).f()).append('\n');
}
private static void checkBoolean(StringBuffer builder) {
builder
+ .append(((iz) new it<Boolean>() {
+ @Override public Boolean t() {
+ return true;
+ }
+ }::t).f()).append(' ')
.append(((iz) ValueAdjustments::z).f()).append(' ')
.append(((iz) ValueAdjustments::Z).f()).append('\n');
}