NI: allow lower bound of flexible type for coercion-to-Unit

Example from
box/inference/coercionToUnitForLambdaReturnTypeWithFlexibleConstraint

// FILE: TestJ.java
public class TestJ {
  public static <T> In<T> materialize() { return null; }
}

// FILE: test.kt

class In<in T>

fun <T> inferred(e: In<T>?, l: () -> T): T = l()

fun box() {
  inferred(TestJ.materialize<Unit>(), { null })
}

`materialize` has flexible type, both for `In<T>` and `T`.
When analyzing `{ null }`, collected type constraints include:
ft<Unit?, Unit> <: T (from ft<In<ft<Unit, Unit?>>, In<ft<Unit, Unit?>>?>)

By allowing the lower bound of flexible type, FIR resolution can visit
`{ null }` with the expected type Unit, which will lead to proper
coercion to Unit at the end.
This commit is contained in:
Jinseong Jeon
2020-12-08 13:26:37 -08:00
committed by Dmitriy Novozhilov
parent b0f6461fa9
commit 0ea6b32c01
@@ -437,6 +437,9 @@ class NewConstraintSystemImpl(
override fun hasUpperOrEqualUnitConstraint(type: KotlinTypeMarker): Boolean {
checkState(State.BUILDING, State.COMPLETION, State.FREEZED)
val constraints = storage.notFixedTypeVariables[type.typeConstructor()]?.constraints ?: return false
return constraints.any { (it.kind == ConstraintKind.UPPER || it.kind == ConstraintKind.EQUALITY) && it.type.isUnit() }
return constraints.any {
(it.kind == ConstraintKind.UPPER || it.kind == ConstraintKind.EQUALITY) &&
it.type.lowerBoundIfFlexible().isUnit()
}
}
}