[NI] Approximate captured types when set them into variable.
Also do not store type with captured type inside possible types. It is hack for now, but without it captured types can flow to resolution and exception will be thrown.
This commit is contained in:
@@ -86,6 +86,7 @@ public class DescriptorResolver {
|
||||
private final ModifiersChecker modifiersChecker;
|
||||
private final WrappedTypeFactory wrappedTypeFactory;
|
||||
private final SyntheticResolveExtension syntheticResolveExtension;
|
||||
private final TypeApproximator typeApproximator;
|
||||
|
||||
public DescriptorResolver(
|
||||
@NotNull AnnotationResolver annotationResolver,
|
||||
@@ -101,7 +102,8 @@ public class DescriptorResolver {
|
||||
@NotNull DestructuringDeclarationResolver destructuringDeclarationResolver,
|
||||
@NotNull ModifiersChecker modifiersChecker,
|
||||
@NotNull WrappedTypeFactory wrappedTypeFactory,
|
||||
@NotNull Project project
|
||||
@NotNull Project project,
|
||||
TypeApproximator approximator
|
||||
) {
|
||||
this.annotationResolver = annotationResolver;
|
||||
this.builtIns = builtIns;
|
||||
@@ -117,6 +119,7 @@ public class DescriptorResolver {
|
||||
this.modifiersChecker = modifiersChecker;
|
||||
this.wrappedTypeFactory = wrappedTypeFactory;
|
||||
this.syntheticResolveExtension = SyntheticResolveExtension.Companion.getInstance(project);
|
||||
typeApproximator = approximator;
|
||||
}
|
||||
|
||||
public List<KotlinType> resolveSupertypes(
|
||||
@@ -666,11 +669,12 @@ public class DescriptorResolver {
|
||||
BindingTrace trace,
|
||||
@NotNull LexicalScope scope
|
||||
) {
|
||||
UnwrappedType approximatedType = typeApproximator.approximateDeclarationType(type, true);
|
||||
VariableDescriptor variableDescriptor = new LocalVariableDescriptor(
|
||||
scope.getOwnerDescriptor(),
|
||||
annotationResolver.resolveAnnotationsWithArguments(scope, parameter.getModifierList(), trace),
|
||||
KtPsiUtil.safeName(parameter.getName()),
|
||||
type,
|
||||
approximatedType,
|
||||
false,
|
||||
false,
|
||||
KotlinSourceElementKt.toSourceElement(parameter)
|
||||
|
||||
+13
-8
@@ -38,7 +38,8 @@ class VariableTypeAndInitializerResolver(
|
||||
private val typeResolver: TypeResolver,
|
||||
private val constantExpressionEvaluator: ConstantExpressionEvaluator,
|
||||
private val delegatedPropertyResolver: DelegatedPropertyResolver,
|
||||
private val wrappedTypeFactory: WrappedTypeFactory
|
||||
private val wrappedTypeFactory: WrappedTypeFactory,
|
||||
private val typeApproximator: TypeApproximator
|
||||
) {
|
||||
companion object {
|
||||
@JvmField
|
||||
@@ -76,7 +77,7 @@ class VariableTypeAndInitializerResolver(
|
||||
|
||||
!variable.hasInitializer() && variable is KtProperty && variableDescriptor is VariableDescriptorWithAccessors &&
|
||||
variable.hasDelegateExpression() ->
|
||||
resolveDelegatedPropertyType(variable, variableDescriptor, scopeForInitializer, dataFlowInfo, trace)
|
||||
resolveDelegatedPropertyType(variable, variableDescriptor, scopeForInitializer, dataFlowInfo, trace, local)
|
||||
|
||||
variable.hasInitializer() -> when {
|
||||
!local ->
|
||||
@@ -84,11 +85,11 @@ class VariableTypeAndInitializerResolver(
|
||||
trace
|
||||
) {
|
||||
PreliminaryDeclarationVisitor.createForDeclaration(variable, trace)
|
||||
val initializerType = resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace)
|
||||
val initializerType = resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace, local)
|
||||
transformAnonymousTypeIfNeeded(variableDescriptor, variable, initializerType, trace)
|
||||
}
|
||||
|
||||
else -> resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace)
|
||||
else -> resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace, local)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
@@ -129,7 +130,8 @@ class VariableTypeAndInitializerResolver(
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
scopeForInitializer: LexicalScope,
|
||||
dataFlowInfo: DataFlowInfo,
|
||||
trace: BindingTrace
|
||||
trace: BindingTrace,
|
||||
local: Boolean
|
||||
) = wrappedTypeFactory.createRecursionIntolerantDeferredType(trace) {
|
||||
val delegateExpression = property.delegateExpression!!
|
||||
val type = delegatedPropertyResolver.resolveDelegateExpression(
|
||||
@@ -139,15 +141,18 @@ class VariableTypeAndInitializerResolver(
|
||||
variableDescriptor, delegateExpression, type, trace, scopeForInitializer, dataFlowInfo
|
||||
)
|
||||
|
||||
getterReturnType ?: ErrorUtils.createErrorType("Type from delegate")
|
||||
getterReturnType?.let { approximateType(it, local) } ?: ErrorUtils.createErrorType("Type from delegate")
|
||||
}
|
||||
|
||||
private fun resolveInitializerType(
|
||||
scope: LexicalScope,
|
||||
initializer: KtExpression,
|
||||
dataFlowInfo: DataFlowInfo,
|
||||
trace: BindingTrace
|
||||
trace: BindingTrace,
|
||||
local: Boolean
|
||||
): KotlinType {
|
||||
return expressionTypingServices.safeGetType(scope, initializer, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo, trace)
|
||||
return approximateType(expressionTypingServices.safeGetType(scope, initializer, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo, trace), local)
|
||||
}
|
||||
|
||||
private fun approximateType(type: KotlinType, local: Boolean): UnwrappedType = typeApproximator.approximateDeclarationType(type, local)
|
||||
}
|
||||
|
||||
+3
-1
@@ -28,6 +28,8 @@ import org.jetbrains.kotlin.types.isError
|
||||
import org.jetbrains.kotlin.types.isFlexible
|
||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||
import org.jetbrains.kotlin.utils.newLinkedHashSetWithExpectedSize
|
||||
import org.jetbrains.kotlin.types.checker.NewCapturedTypeConstructor
|
||||
import org.jetbrains.kotlin.types.typeUtil.contains
|
||||
import java.util.*
|
||||
|
||||
internal class DelegatingDataFlowInfo private constructor(
|
||||
@@ -329,7 +331,7 @@ internal class DelegatingDataFlowInfo private constructor(
|
||||
for (value in typeInfo.keys()) {
|
||||
for (type in typeInfo[value]) {
|
||||
// Remove original type (see also KT-10666)
|
||||
if (value.type == type) {
|
||||
if (value.type == type || type.contains { it.constructor is NewCapturedTypeConstructor }) {
|
||||
toDelete.put(value, type)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.types
|
||||
|
||||
import org.jetbrains.kotlin.resolve.calls.components.CommonSupertypeCalculator
|
||||
import org.jetbrains.kotlin.resolve.calls.USE_NEW_INFERENCE
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableTypeConstructor
|
||||
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration.IntersectionStrategy.*
|
||||
import org.jetbrains.kotlin.types.checker.*
|
||||
@@ -58,6 +59,7 @@ open class TypeApproximatorConfiguration {
|
||||
|
||||
object PublicDeclaration : AllFlexibleSameValue() {
|
||||
override val allFlexible get() = true
|
||||
override val errorType get() = true
|
||||
}
|
||||
|
||||
abstract class AbstractCapturedTypesApproximation(val approximatedCapturedStatus: CaptureStatus): TypeApproximatorConfiguration.AllFlexibleSameValue() {
|
||||
@@ -78,6 +80,12 @@ class TypeApproximator(private val commonSupertypeCalculator: CommonSupertypeCal
|
||||
private val referenceApproximateToSuperType = this::approximateToSuperType
|
||||
private val referenceApproximateToSubType = this::approximateToSubType
|
||||
|
||||
fun approximateDeclarationType(baseType: KotlinType, local: Boolean): UnwrappedType {
|
||||
if (!USE_NEW_INFERENCE) return baseType.unwrap()
|
||||
|
||||
val configuration = if (local) TypeApproximatorConfiguration.LocalDeclaration else TypeApproximatorConfiguration.PublicDeclaration
|
||||
return approximateToSuperType(baseType.unwrap(), configuration) ?: baseType.unwrap()
|
||||
}
|
||||
|
||||
// null means that this input type is the result, i.e. input type not contains not-allowed kind of types
|
||||
// type <: resultType
|
||||
|
||||
Reference in New Issue
Block a user