diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java index a0b41b54549..e7e49db1971 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java @@ -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 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) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt index 9256129bb2e..a170bcb0540 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeAndInitializerResolver.kt @@ -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) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/smartcasts/DelegatingDataFlowInfo.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/smartcasts/DelegatingDataFlowInfo.kt index b88de259f43..eb8624860d7 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/smartcasts/DelegatingDataFlowInfo.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/smartcasts/DelegatingDataFlowInfo.kt @@ -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) } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt b/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt index 6ff74ad76ff..efab5200e72 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt @@ -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