From f7091dd1e9650c45d02a62094dc8a900b11cc64a Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Thu, 25 Apr 2019 18:20:45 +0300 Subject: [PATCH] [NI] Uncapture captured types in diagnostics --- .../DiagnosticReporterByTrackingStrategy.kt | 27 ++++++++++++++++--- .../typeAliasConstructorForProjection.ni.txt | 2 +- .../org/jetbrains/kotlin/types/TypeUtils.kt | 24 +++++++++++++++++ 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt index 4aae14c1333..21768a5dc1b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluat import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.typeUtil.unCapture import org.jetbrains.kotlin.utils.addToStdlib.safeAs class DiagnosticReporterByTrackingStrategy( @@ -212,24 +213,42 @@ class DiagnosticReporterByTrackingStrategy( val constraintError = diagnostic as NewConstraintError val position = constraintError.position.from val argument = (position as? ArgumentConstraintPosition)?.argument - ?: (position as? ReceiverConstraintPosition)?.argument + ?: (position as? ReceiverConstraintPosition)?.argument argument?.let { val expression = it.psiExpression ?: return val deparenthesized = KtPsiUtil.safeDeparenthesize(expression) if (reportConstantTypeMismatch(constraintError, deparenthesized)) return - trace.report(Errors.TYPE_MISMATCH.on(deparenthesized, constraintError.upperKotlinType, constraintError.lowerKotlinType)) + trace.report( + Errors.TYPE_MISMATCH.on( + deparenthesized, + constraintError.upperKotlinType.unCapture(), + constraintError.lowerKotlinType.unCapture() + ) + ) } (position as? ExpectedTypeConstraintPosition)?.let { val call = it.topLevelCall.psiKotlinCall.psiCall.callElement.safeAs() reportIfNonNull(call) { - trace.report(Errors.TYPE_MISMATCH.on(it, constraintError.upperKotlinType, constraintError.lowerKotlinType)) + trace.report( + Errors.TYPE_MISMATCH.on( + it, + constraintError.upperKotlinType.unCapture(), + constraintError.lowerKotlinType.unCapture() + ) + ) } } (position as? ExplicitTypeParameterConstraintPosition)?.let { val typeArgumentReference = (it.typeArgument as SimpleTypeArgumentImpl).typeReference - trace.report(UPPER_BOUND_VIOLATED.on(typeArgumentReference, constraintError.upperKotlinType, constraintError.lowerKotlinType)) + trace.report( + UPPER_BOUND_VIOLATED.on( + typeArgumentReference, + constraintError.upperKotlinType, + constraintError.lowerKotlinType + ) + ) } } diff --git a/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorForProjection.ni.txt b/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorForProjection.ni.txt index 92351251be0..004785feb88 100644 --- a/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorForProjection.ni.txt +++ b/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorForProjection.ni.txt @@ -3,7 +3,7 @@ package public val test1: CStar /* = C<*> */ public val test2: CIn /* = C */ public val test3: COut /* = C */ -public val test4: CT /* = C */ +public val test4: [ERROR : Type for CT<*>()] public val test5: CT /* = C<*> */> /* = C /* = C<*> */> */ public final class C { diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt index 3f074cbc687..77e76db2817 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt @@ -26,7 +26,9 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.checker.NewCapturedType +import org.jetbrains.kotlin.types.checker.NewCapturedTypeConstructor import org.jetbrains.kotlin.types.checker.NewTypeVariableConstructor +import org.jetbrains.kotlin.utils.addToStdlib.safeAs import java.util.* enum class TypeNullability { @@ -251,4 +253,26 @@ fun KotlinType.expandIntersectionTypeIfNecessary(): Collection { } else { types } +} + +fun KotlinType.unCapture(): KotlinType = unwrap().unCapture() + +fun UnwrappedType.unCapture(): UnwrappedType = when (this) { + is AbbreviatedType -> unCapture() + is SimpleType -> unCapture() + is FlexibleType -> FlexibleTypeImpl(lowerBound.unCapture(), upperBound.unCapture()) +} + +fun SimpleType.unCapture(): SimpleType { + val newArguments = arguments.map { projection -> + projection.type.constructor.safeAs()?.let { + it.projection + } ?: projection + } + return replace(newArguments) +} + +fun AbbreviatedType.unCapture(): SimpleType { + val newType = expandedType.unCapture() + return AbbreviatedType(newType, abbreviation) } \ No newline at end of file