[NI] Remove hack for special functions

Treating special functions for `if`, `when`, `try`, `?:` as not accepting `Nothing` result type is incorrect.
Making so leads to cases with uninferred `Nothing` result type for inner calls and lost data flow info.
This commit is contained in:
Pavel Kirpichenkov
2019-12-26 14:57:47 +03:00
parent 9a12641fde
commit 2d21b82501
18 changed files with 87 additions and 66 deletions
@@ -40,10 +40,6 @@ interface KotlinResolutionStatelessCallbacks {
fun createConstraintSystemForOverloadResolution(
constraintInjector: ConstraintInjector, builtIns: KotlinBuiltIns
): SimpleConstraintSystem
fun isSpecialFunctionTypeParameterName(name: Name): Boolean
fun isExclExclTypeParameterName(name: Name): Boolean
}
// This components hold state (trace). Work with this carefully.
@@ -30,8 +30,7 @@ import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext
class ResultTypeResolver(
val typeApproximator: AbstractTypeApproximator,
val trivialConstraintTypeInferenceOracle: TrivialConstraintTypeInferenceOracle,
private val statelessCallbacks: KotlinResolutionStatelessCallbacks? // TODO injection in FIR
val trivialConstraintTypeInferenceOracle: TrivialConstraintTypeInferenceOracle
) {
interface Context : TypeSystemInferenceExtensionContext {
fun isProperType(type: KotlinTypeMarker): Boolean
@@ -85,20 +84,12 @@ class ResultTypeResolver(
if (!checkConstraint(this, constraint.type, constraint.kind, resultType)) return false
}
if (!trivialConstraintTypeInferenceOracle.isSuitableResultedType(resultType)) {
if (nothingIsForbiddenFor(variableWithConstraints.typeVariable)) return false
if (resultType.isNullableType() && checkSingleLowerNullabilityConstraint(filteredConstraints)) return false
}
return true
}
private fun nothingIsForbiddenFor(variable: TypeVariableMarker): Boolean {
val parameterName = variable.safeAs<TypeVariableFromCallableDescriptor>()?.originalTypeParameter?.name ?: return false
val isSpecialFunctionParameter = statelessCallbacks?.isSpecialFunctionTypeParameterName(parameterName) ?: false
val isFromExclExcl = isSpecialFunctionParameter && statelessCallbacks?.isExclExclTypeParameterName(parameterName) ?: false
return isSpecialFunctionParameter && !isFromExclExcl
}
private fun checkSingleLowerNullabilityConstraint(constraints: List<Constraint>): Boolean {
return constraints.singleOrNull { it.kind.isLower() }?.isNullabilityConstraint ?: false
}