From 1fb713342bdb0028f09a8487004c394c50777026 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Fri, 26 Sep 2014 17:45:39 +0400 Subject: [PATCH] Capture types only on the top level --- .../jet/lang/diagnostics/Errors.java | 1 + .../rendering/DefaultErrorMessages.java | 1 + .../lang/diagnostics/rendering/Renderers.java | 59 ++++++++++++++++--- .../calls/tasks/AbstractTracingStrategy.java | 6 +- .../checkStatus/conflictingConstraints.bounds | 1 + .../checkStatus/successful.bounds | 1 + .../typeConstructorMismatch.bounds | 1 + .../checkStatus/unknownParameters.bounds | 1 + .../checkStatus/violatedUpperBound.bounds | 1 + .../computeValues/contradiction.bounds | 1 + .../computeValues/subTypeOfUpperBounds.bounds | 1 + .../superTypeOfLowerBounds1.bounds | 1 + .../superTypeOfLowerBounds2.bounds | 1 + .../integerValueTypes/byteOverflow.bounds | 1 + .../integerValueTypes/defaultLong.bounds | 1 + .../integerValueTypes/numberAndAny.bounds | 1 + .../integerValueTypes/numberAndString.bounds | 1 + .../integerValueTypes/severalNumbers.bounds | 1 + .../integerValueTypes/simpleByte.bounds | 1 + .../integerValueTypes/simpleInt.bounds | 1 + .../integerValueTypes/simpleShort.bounds | 1 + .../severalVariables/simpleDependency.bounds | 1 + .../constraintSystem/variance/consumer.bounds | 1 + .../variance/invariant.bounds | 1 + .../constraintSystem/variance/producer.bounds | 1 + .../captureTypeOnlyOnTopLevel.kt | 9 +++ .../captureTypeOnlyOnTopLevel.txt | 4 ++ .../checkers/JetDiagnosticsTestGenerated.java | 6 ++ .../calls/inference/ConstraintSystemImpl.kt | 13 +++- .../calls/inference/ConstraintSystemStatus.kt | 3 + 30 files changed, 111 insertions(+), 12 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/inference/capturedTypes/captureTypeOnlyOnTopLevel.kt create mode 100644 compiler/testData/diagnostics/tests/inference/capturedTypes/captureTypeOnlyOnTopLevel.txt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java index 1571aa579da..5bf4fae7744 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java @@ -396,6 +396,7 @@ public interface Errors { DiagnosticFactory1 TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER = DiagnosticFactory1.create(ERROR); DiagnosticFactory1 TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS = DiagnosticFactory1.create(ERROR); + DiagnosticFactory1 TYPE_INFERENCE_CANNOT_CAPTURE_TYPES = DiagnosticFactory1.create(ERROR); DiagnosticFactory1 TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH = DiagnosticFactory1.create(ERROR); DiagnosticFactory1 TYPE_INFERENCE_UPPER_BOUND_VIOLATED = DiagnosticFactory1.create(ERROR); DiagnosticFactory2 TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH = DiagnosticFactory2.create(ERROR); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java index cad14835669..a26f6efe6b2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java @@ -487,6 +487,7 @@ public class DefaultErrorMessages { MAP.put(CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS, "Cannot create an instance of an abstract class"); MAP.put(TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS, "Type inference failed: {0}", TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS_RENDERER); + MAP.put(TYPE_INFERENCE_CANNOT_CAPTURE_TYPES, "Type inference failed: {0}", TYPE_INFERENCE_CANNOT_CAPTURE_TYPES_RENDERER); MAP.put(TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER, "Type inference failed: {0}", TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER_RENDERER); MAP.put(TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH, "Type inference failed: {0}", TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH_RENDERER); MAP.put(TYPE_INFERENCE_UPPER_BOUND_VIOLATED, "{0}", TYPE_INFERENCE_UPPER_BOUND_VIOLATED_RENDERER); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java index 8f2092e0d34..2e497089b27 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java @@ -34,10 +34,7 @@ import org.jetbrains.jet.lang.resolve.calls.inference.*; import org.jetbrains.jet.lang.resolve.calls.inference.constraintPosition.ConstraintPosition; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.name.Name; -import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.jet.lang.types.TypeSubstitutor; -import org.jetbrains.jet.lang.types.TypeUtils; -import org.jetbrains.jet.lang.types.Variance; +import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.renderer.DescriptorRenderer; import org.jetbrains.jet.renderer.Renderer; @@ -214,6 +211,15 @@ public class Renderers { } }; + public static final Renderer TYPE_INFERENCE_CANNOT_CAPTURE_TYPES_RENDERER = + new Renderer() { + @NotNull + @Override + public String render(@NotNull InferenceErrorData inferenceErrorData) { + return renderCannotCaptureTypeParameterError(inferenceErrorData, TabledDescriptorRenderer.create()).toString(); + } + }; + public static TabledDescriptorRenderer renderConflictingSubstitutionsInferenceError(InferenceErrorData inferenceErrorData, TabledDescriptorRenderer result) { LOG.assertTrue(inferenceErrorData.constraintSystem.getStatus().hasConflictingConstraints(), renderDebugMessage( @@ -277,8 +283,11 @@ public class Renderers { return result; } - public static TabledDescriptorRenderer renderTypeConstructorMismatchError(final InferenceErrorData inferenceErrorData, - TabledDescriptorRenderer renderer) { + @NotNull + public static TabledDescriptorRenderer renderTypeConstructorMismatchError( + final @NotNull InferenceErrorData inferenceErrorData, + @NotNull TabledDescriptorRenderer renderer + ) { Predicate isErrorPosition = new Predicate() { @Override public boolean apply(ConstraintPosition constraintPosition) { @@ -294,8 +303,11 @@ public class Renderers { isErrorPosition)); } - public static TabledDescriptorRenderer renderNoInformationForParameterError(InferenceErrorData inferenceErrorData, - TabledDescriptorRenderer result) { + @NotNull + public static TabledDescriptorRenderer renderNoInformationForParameterError( + @NotNull InferenceErrorData inferenceErrorData, + @NotNull TabledDescriptorRenderer result + ) { TypeParameterDescriptor firstUnknownParameter = null; for (TypeParameterDescriptor typeParameter : inferenceErrorData.constraintSystem.getTypeVariables()) { if (inferenceErrorData.constraintSystem.getTypeBounds(typeParameter).isEmpty()) { @@ -376,6 +388,37 @@ public class Renderers { return result; } + @NotNull + public static TabledDescriptorRenderer renderCannotCaptureTypeParameterError( + @NotNull InferenceErrorData inferenceErrorData, + @NotNull TabledDescriptorRenderer result + ) { + ConstraintSystem constraintSystem = inferenceErrorData.constraintSystem; + TypeParameterDescriptor typeParameterWithCapturedConstraint = null; + CapturedTypeConstructor capturedTypeConstructor = null; + for (TypeParameterDescriptor typeParameter : constraintSystem.getTypeVariables()) { + TypeBounds typeBounds = constraintSystem.getTypeBounds(typeParameter); + for (TypeBounds.Bound bound : typeBounds.getBounds()) { + TypeConstructor constructor = bound.getConstrainingType().getConstructor(); + if (constructor instanceof CapturedTypeConstructor) { + typeParameterWithCapturedConstraint = typeParameter; + capturedTypeConstructor = (CapturedTypeConstructor) constructor; + } + } + } + if (capturedTypeConstructor == null) { + LOG.error(renderDebugMessage("There is no captured type in bounds, but there is an error 'cannot capture type parameter'", + inferenceErrorData)); + return result; + } + + result.text(newText().normal("'" + typeParameterWithCapturedConstraint.getName() + "'" + + " cannot capture " + + "'" + capturedTypeConstructor.getTypeProjection() + "'. " + + "Only top level type projections can be captured")); + return result; + } + public static final Renderer> CLASSES_OR_SEPARATED = new Renderer>() { @NotNull @Override diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/AbstractTracingStrategy.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/AbstractTracingStrategy.java index 2efdcb6c8fc..8dd04f743fe 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/AbstractTracingStrategy.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/AbstractTracingStrategy.java @@ -226,9 +226,9 @@ public abstract class AbstractTracingStrategy implements TracingStrategy { assert !noExpectedType(data.expectedType) : "Expected type doesn't exist, but there is an expected type mismatch error"; trace.report(TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH.on(reference, data.expectedType, substitutedReturnType)); } - //else if (status.hasConflictWithCapturedType()) { - // trace.report(TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS.on(reference, data)); - //} + else if (status.hasCannotCaptureTypesError()) { + trace.report(TYPE_INFERENCE_CANNOT_CAPTURE_TYPES.on(reference, data)); + } else if (status.hasViolatedUpperBound()) { trace.report(TYPE_INFERENCE_UPPER_BOUND_VIOLATED.on(reference, data)); } diff --git a/compiler/testData/constraintSystem/checkStatus/conflictingConstraints.bounds b/compiler/testData/constraintSystem/checkStatus/conflictingConstraints.bounds index 4083725fb79..5c41241ab88 100644 --- a/compiler/testData/constraintSystem/checkStatus/conflictingConstraints.bounds +++ b/compiler/testData/constraintSystem/checkStatus/conflictingConstraints.bounds @@ -6,6 +6,7 @@ SUPERTYPE T String type parameter bounds: T <: kotlin.Int(SPECIAL), >: kotlin.String(SPECIAL) status: +-hasCannotCaptureTypesError: false -hasConflictingConstraints: true -hasContradiction: true -hasErrorInConstrainingTypes: false diff --git a/compiler/testData/constraintSystem/checkStatus/successful.bounds b/compiler/testData/constraintSystem/checkStatus/successful.bounds index 104cd410c48..bdc70204b1c 100644 --- a/compiler/testData/constraintSystem/checkStatus/successful.bounds +++ b/compiler/testData/constraintSystem/checkStatus/successful.bounds @@ -6,6 +6,7 @@ SUPERTYPE T Int type parameter bounds: T <: kotlin.Int(SPECIAL), >: kotlin.Int(SPECIAL) status: +-hasCannotCaptureTypesError: false -hasConflictingConstraints: false -hasContradiction: false -hasErrorInConstrainingTypes: false diff --git a/compiler/testData/constraintSystem/checkStatus/typeConstructorMismatch.bounds b/compiler/testData/constraintSystem/checkStatus/typeConstructorMismatch.bounds index ccc74cf79bd..b53d50cc22b 100644 --- a/compiler/testData/constraintSystem/checkStatus/typeConstructorMismatch.bounds +++ b/compiler/testData/constraintSystem/checkStatus/typeConstructorMismatch.bounds @@ -5,6 +5,7 @@ SUBTYPE List Int type parameter bounds: T status: +-hasCannotCaptureTypesError: false -hasConflictingConstraints: false -hasContradiction: true -hasErrorInConstrainingTypes: false diff --git a/compiler/testData/constraintSystem/checkStatus/unknownParameters.bounds b/compiler/testData/constraintSystem/checkStatus/unknownParameters.bounds index 9f653baf4a2..f6e6b7f85d6 100644 --- a/compiler/testData/constraintSystem/checkStatus/unknownParameters.bounds +++ b/compiler/testData/constraintSystem/checkStatus/unknownParameters.bounds @@ -5,6 +5,7 @@ SUBTYPE Any Any type parameter bounds: T status: +-hasCannotCaptureTypesError: false -hasConflictingConstraints: false -hasContradiction: false -hasErrorInConstrainingTypes: false diff --git a/compiler/testData/constraintSystem/checkStatus/violatedUpperBound.bounds b/compiler/testData/constraintSystem/checkStatus/violatedUpperBound.bounds index e96c7e4abf6..b2e152f04dc 100644 --- a/compiler/testData/constraintSystem/checkStatus/violatedUpperBound.bounds +++ b/compiler/testData/constraintSystem/checkStatus/violatedUpperBound.bounds @@ -6,6 +6,7 @@ SUBTYPE T String weak type parameter bounds: T <: kotlin.Int(SPECIAL), <: kotlin.String(TYPE_BOUND_POSITION(0)) status: +-hasCannotCaptureTypesError: false -hasConflictingConstraints: true -hasContradiction: true -hasErrorInConstrainingTypes: false diff --git a/compiler/testData/constraintSystem/computeValues/contradiction.bounds b/compiler/testData/constraintSystem/computeValues/contradiction.bounds index 0f508fa78c5..923bf99606b 100644 --- a/compiler/testData/constraintSystem/computeValues/contradiction.bounds +++ b/compiler/testData/constraintSystem/computeValues/contradiction.bounds @@ -6,6 +6,7 @@ SUPERTYPE T A type parameter bounds: T <: B(SPECIAL), >: A(SPECIAL) status: +-hasCannotCaptureTypesError: false -hasConflictingConstraints: true -hasContradiction: true -hasErrorInConstrainingTypes: false diff --git a/compiler/testData/constraintSystem/computeValues/subTypeOfUpperBounds.bounds b/compiler/testData/constraintSystem/computeValues/subTypeOfUpperBounds.bounds index 0f8a0021f54..a9e09d438c8 100644 --- a/compiler/testData/constraintSystem/computeValues/subTypeOfUpperBounds.bounds +++ b/compiler/testData/constraintSystem/computeValues/subTypeOfUpperBounds.bounds @@ -6,6 +6,7 @@ SUBTYPE T B type parameter bounds: T <: A(SPECIAL), <: B(SPECIAL) status: +-hasCannotCaptureTypesError: false -hasConflictingConstraints: false -hasContradiction: false -hasErrorInConstrainingTypes: false diff --git a/compiler/testData/constraintSystem/computeValues/superTypeOfLowerBounds1.bounds b/compiler/testData/constraintSystem/computeValues/superTypeOfLowerBounds1.bounds index 1b632359e1b..584a66d7afb 100644 --- a/compiler/testData/constraintSystem/computeValues/superTypeOfLowerBounds1.bounds +++ b/compiler/testData/constraintSystem/computeValues/superTypeOfLowerBounds1.bounds @@ -6,6 +6,7 @@ SUPERTYPE T C type parameter bounds: T <: A(SPECIAL), >: C(SPECIAL) status: +-hasCannotCaptureTypesError: false -hasConflictingConstraints: false -hasContradiction: false -hasErrorInConstrainingTypes: false diff --git a/compiler/testData/constraintSystem/computeValues/superTypeOfLowerBounds2.bounds b/compiler/testData/constraintSystem/computeValues/superTypeOfLowerBounds2.bounds index 57f7b650266..318ac21cd9b 100644 --- a/compiler/testData/constraintSystem/computeValues/superTypeOfLowerBounds2.bounds +++ b/compiler/testData/constraintSystem/computeValues/superTypeOfLowerBounds2.bounds @@ -7,6 +7,7 @@ SUPERTYPE T C type parameter bounds: T <: A(SPECIAL), >: B(SPECIAL), >: C(SPECIAL) status: +-hasCannotCaptureTypesError: false -hasConflictingConstraints: false -hasContradiction: false -hasErrorInConstrainingTypes: false diff --git a/compiler/testData/constraintSystem/integerValueTypes/byteOverflow.bounds b/compiler/testData/constraintSystem/integerValueTypes/byteOverflow.bounds index 5d440ca8665..94f27a74d2f 100644 --- a/compiler/testData/constraintSystem/integerValueTypes/byteOverflow.bounds +++ b/compiler/testData/constraintSystem/integerValueTypes/byteOverflow.bounds @@ -6,6 +6,7 @@ SUBTYPE T Byte type parameter bounds: T >: IntegerValueType(1000)(SPECIAL), <: kotlin.Byte(SPECIAL) status: +-hasCannotCaptureTypesError: false -hasConflictingConstraints: true -hasContradiction: true -hasErrorInConstrainingTypes: false diff --git a/compiler/testData/constraintSystem/integerValueTypes/defaultLong.bounds b/compiler/testData/constraintSystem/integerValueTypes/defaultLong.bounds index a6a216d1d57..b347c499c6d 100644 --- a/compiler/testData/constraintSystem/integerValueTypes/defaultLong.bounds +++ b/compiler/testData/constraintSystem/integerValueTypes/defaultLong.bounds @@ -6,6 +6,7 @@ SUPERTYPE T IntegerValueType(10000000000) type parameter bounds: T >: IntegerValueType(1)(SPECIAL), >: IntegerValueType(10000000000)(SPECIAL) status: +-hasCannotCaptureTypesError: false -hasConflictingConstraints: false -hasContradiction: false -hasErrorInConstrainingTypes: false diff --git a/compiler/testData/constraintSystem/integerValueTypes/numberAndAny.bounds b/compiler/testData/constraintSystem/integerValueTypes/numberAndAny.bounds index e3baf10f867..adadb2fe28c 100644 --- a/compiler/testData/constraintSystem/integerValueTypes/numberAndAny.bounds +++ b/compiler/testData/constraintSystem/integerValueTypes/numberAndAny.bounds @@ -6,6 +6,7 @@ SUBTYPE T Any type parameter bounds: T >: IntegerValueType(1)(SPECIAL), <: kotlin.Any(SPECIAL) status: +-hasCannotCaptureTypesError: false -hasConflictingConstraints: false -hasContradiction: false -hasErrorInConstrainingTypes: false diff --git a/compiler/testData/constraintSystem/integerValueTypes/numberAndString.bounds b/compiler/testData/constraintSystem/integerValueTypes/numberAndString.bounds index d26c781929a..fdb976e6657 100644 --- a/compiler/testData/constraintSystem/integerValueTypes/numberAndString.bounds +++ b/compiler/testData/constraintSystem/integerValueTypes/numberAndString.bounds @@ -6,6 +6,7 @@ SUPERTYPE T String type parameter bounds: T >: IntegerValueType(1)(SPECIAL), >: kotlin.String(SPECIAL) status: +-hasCannotCaptureTypesError: false -hasConflictingConstraints: false -hasContradiction: false -hasErrorInConstrainingTypes: false diff --git a/compiler/testData/constraintSystem/integerValueTypes/severalNumbers.bounds b/compiler/testData/constraintSystem/integerValueTypes/severalNumbers.bounds index 11423aa3767..a42d6b14b06 100644 --- a/compiler/testData/constraintSystem/integerValueTypes/severalNumbers.bounds +++ b/compiler/testData/constraintSystem/integerValueTypes/severalNumbers.bounds @@ -6,6 +6,7 @@ SUPERTYPE T IntegerValueType(1000) type parameter bounds: T >: IntegerValueType(1)(SPECIAL), >: IntegerValueType(1000)(SPECIAL) status: +-hasCannotCaptureTypesError: false -hasConflictingConstraints: false -hasContradiction: false -hasErrorInConstrainingTypes: false diff --git a/compiler/testData/constraintSystem/integerValueTypes/simpleByte.bounds b/compiler/testData/constraintSystem/integerValueTypes/simpleByte.bounds index 6c5a458552d..cc023a871ae 100644 --- a/compiler/testData/constraintSystem/integerValueTypes/simpleByte.bounds +++ b/compiler/testData/constraintSystem/integerValueTypes/simpleByte.bounds @@ -6,6 +6,7 @@ SUBTYPE T Byte type parameter bounds: T >: IntegerValueType(1)(SPECIAL), <: kotlin.Byte(SPECIAL) status: +-hasCannotCaptureTypesError: false -hasConflictingConstraints: false -hasContradiction: false -hasErrorInConstrainingTypes: false diff --git a/compiler/testData/constraintSystem/integerValueTypes/simpleInt.bounds b/compiler/testData/constraintSystem/integerValueTypes/simpleInt.bounds index 665dfb19233..a6961daeb68 100644 --- a/compiler/testData/constraintSystem/integerValueTypes/simpleInt.bounds +++ b/compiler/testData/constraintSystem/integerValueTypes/simpleInt.bounds @@ -5,6 +5,7 @@ SUPERTYPE T IntegerValueType(1) type parameter bounds: T >: IntegerValueType(1)(SPECIAL) status: +-hasCannotCaptureTypesError: false -hasConflictingConstraints: false -hasContradiction: false -hasErrorInConstrainingTypes: false diff --git a/compiler/testData/constraintSystem/integerValueTypes/simpleShort.bounds b/compiler/testData/constraintSystem/integerValueTypes/simpleShort.bounds index 2877c8414ea..04cdd23bcae 100644 --- a/compiler/testData/constraintSystem/integerValueTypes/simpleShort.bounds +++ b/compiler/testData/constraintSystem/integerValueTypes/simpleShort.bounds @@ -6,6 +6,7 @@ SUBTYPE T Short type parameter bounds: T >: IntegerValueType(1)(SPECIAL), <: kotlin.Short(SPECIAL) status: +-hasCannotCaptureTypesError: false -hasConflictingConstraints: false -hasContradiction: false -hasErrorInConstrainingTypes: false diff --git a/compiler/testData/constraintSystem/severalVariables/simpleDependency.bounds b/compiler/testData/constraintSystem/severalVariables/simpleDependency.bounds index b146606e34c..8469234f4fe 100644 --- a/compiler/testData/constraintSystem/severalVariables/simpleDependency.bounds +++ b/compiler/testData/constraintSystem/severalVariables/simpleDependency.bounds @@ -6,6 +6,7 @@ type parameter bounds: T <: kotlin.Int(SPECIAL) P <: ???(TYPE_BOUND_POSITION(1)), <: kotlin.Int(COMPOUND_CONSTRAINT_POSITION(TYPE_BOUND_POSITION(1), SPECIAL) status: +-hasCannotCaptureTypesError: false -hasConflictingConstraints: false -hasContradiction: false -hasErrorInConstrainingTypes: false diff --git a/compiler/testData/constraintSystem/variance/consumer.bounds b/compiler/testData/constraintSystem/variance/consumer.bounds index 466e95d745f..460d635c820 100644 --- a/compiler/testData/constraintSystem/variance/consumer.bounds +++ b/compiler/testData/constraintSystem/variance/consumer.bounds @@ -5,6 +5,7 @@ SUBTYPE Consumer Consumer type parameter bounds: T <: A(SPECIAL) status: +-hasCannotCaptureTypesError: false -hasConflictingConstraints: false -hasContradiction: false -hasErrorInConstrainingTypes: false diff --git a/compiler/testData/constraintSystem/variance/invariant.bounds b/compiler/testData/constraintSystem/variance/invariant.bounds index 41ba87c7485..957eb13f98b 100644 --- a/compiler/testData/constraintSystem/variance/invariant.bounds +++ b/compiler/testData/constraintSystem/variance/invariant.bounds @@ -5,6 +5,7 @@ SUBTYPE My My type parameter bounds: T := A(SPECIAL) status: +-hasCannotCaptureTypesError: false -hasConflictingConstraints: false -hasContradiction: false -hasErrorInConstrainingTypes: false diff --git a/compiler/testData/constraintSystem/variance/producer.bounds b/compiler/testData/constraintSystem/variance/producer.bounds index b310664e485..47b00045c22 100644 --- a/compiler/testData/constraintSystem/variance/producer.bounds +++ b/compiler/testData/constraintSystem/variance/producer.bounds @@ -5,6 +5,7 @@ SUBTYPE Producer Producer type parameter bounds: T >: A(SPECIAL) status: +-hasCannotCaptureTypesError: false -hasConflictingConstraints: false -hasContradiction: false -hasErrorInConstrainingTypes: false diff --git a/compiler/testData/diagnostics/tests/inference/capturedTypes/captureTypeOnlyOnTopLevel.kt b/compiler/testData/diagnostics/tests/inference/capturedTypes/captureTypeOnlyOnTopLevel.kt new file mode 100644 index 00000000000..f3fd894ca32 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/capturedTypes/captureTypeOnlyOnTopLevel.kt @@ -0,0 +1,9 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE + +fun foo(array: Array>): Array> = array + +fun test(array: Array>) { + foo(array) + + val f: Array> = foo(array) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/capturedTypes/captureTypeOnlyOnTopLevel.txt b/compiler/testData/diagnostics/tests/inference/capturedTypes/captureTypeOnlyOnTopLevel.txt new file mode 100644 index 00000000000..8ef8e5e00f1 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/capturedTypes/captureTypeOnlyOnTopLevel.txt @@ -0,0 +1,4 @@ +package + +internal fun foo(/*0*/ array: kotlin.Array>): kotlin.Array> +internal fun test(/*0*/ array: kotlin.Array>): kotlin.Unit diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 1c687543c7c..5e620012ced 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -5123,6 +5123,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/capturedTypes/kt2872.kt"); doTest(fileName); } + + @TestMetadata("captureTypeOnlyOnTopLevel.kt") + public void testCaptureTypeOnlyOnTopLevel() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/capturedTypes/captureTypeOnlyOnTopLevel.kt"); + doTest(fileName); + } } @TestMetadata("compiler/testData/diagnostics/tests/inference/constraints") diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.kt b/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.kt index aed76d2da43..6341625ac9c 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.kt +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.kt @@ -56,13 +56,14 @@ public class ConstraintSystemImpl : ConstraintSystem { private val typeParameterBounds = LinkedHashMap() private val errorConstraintPositions = HashSet() private var hasErrorInConstrainingTypes: Boolean = false + private var cannotCaptureTypesError: Boolean = false private val constraintSystemStatus = object : ConstraintSystemStatus { // for debug ConstraintsUtil.getDebugMessageForStatus might be used override fun isSuccessful() = !hasContradiction() && !hasUnknownParameters() - override fun hasContradiction() = hasTypeConstructorMismatch() || hasConflictingConstraints() + override fun hasContradiction() = hasTypeConstructorMismatch() || hasConflictingConstraints() || hasCannotCaptureTypesError() override fun hasViolatedUpperBound(): Boolean { if (isSuccessful()) return false @@ -104,6 +105,8 @@ public class ConstraintSystemImpl : ConstraintSystem { } override fun hasErrorInConstrainingTypes() = hasErrorInConstrainingTypes + + override fun hasCannotCaptureTypesError() = cannotCaptureTypesError } private fun getParameterToInferredValueMap(typeParameterBounds: Map, getDefaultTypeProjection: Function1): Map { @@ -195,6 +198,7 @@ public class ConstraintSystemImpl : ConstraintSystem { newSystem.errorConstraintPositions.addAll(errorConstraintPositions.filter(filterConstraintPosition)) //todo if 'filterConstraintPosition' is not trivial, it's incorrect to just copy 'hasErrorInConstrainingTypes' newSystem.hasErrorInConstrainingTypes = hasErrorInConstrainingTypes + newSystem.cannotCaptureTypesError = cannotCaptureTypesError return newSystem } @@ -210,7 +214,10 @@ public class ConstraintSystemImpl : ConstraintSystem { private fun addConstraint(constraintKind: ConstraintKind, subType: JetType?, superType: JetType?, constraintPosition: ConstraintPosition) { val typeCheckingProcedure = TypeCheckingProcedure(object : TypingConstraints { + private var isTopLevel = true + override fun assertEqualTypes(a: JetType, b: JetType, typeCheckingProcedure: TypeCheckingProcedure): Boolean { + isTopLevel = false doAddConstraint(EQUAL, a, b, constraintPosition, typeCheckingProcedure) return true @@ -221,12 +228,16 @@ public class ConstraintSystemImpl : ConstraintSystem { } override fun assertSubtype(subtype: JetType, supertype: JetType, typeCheckingProcedure: TypeCheckingProcedure): Boolean { + isTopLevel = false doAddConstraint(SUB_TYPE, subtype, supertype, constraintPosition, typeCheckingProcedure) return true } override fun capture(typeVariable: JetType, typeProjection: TypeProjection): Boolean { if (isMyTypeVariable(typeVariable) && constraintPosition.isCaptureAllowed()) { + if (!isTopLevel) { + cannotCaptureTypesError = true + } generateTypeParameterCaptureConstraint(typeVariable, typeProjection, constraintPosition) return true } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemStatus.kt b/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemStatus.kt index 6adca55d559..793fdf67415 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemStatus.kt +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemStatus.kt @@ -85,4 +85,7 @@ public trait ConstraintSystemStatus { * Is used not to generate type inference error if there was one in argument types. */ public fun hasErrorInConstrainingTypes(): Boolean + + //todo comment + public fun hasCannotCaptureTypesError(): Boolean } \ No newline at end of file