Type variable with non-trivial upper bound cannot capture 'in' projection
This commit is contained in:
@@ -36,6 +36,7 @@ import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||
import org.jetbrains.jet.renderer.Renderer;
|
||||
|
||||
@@ -412,10 +413,20 @@ public class Renderers {
|
||||
return result;
|
||||
}
|
||||
|
||||
String explanation;
|
||||
JetType upperBound = typeParameterWithCapturedConstraint.getUpperBoundsAsType();
|
||||
if (!KotlinBuiltIns.isNullableAny(upperBound)
|
||||
&& capturedTypeConstructor.getTypeProjection().getProjectionKind() == Variance.IN_VARIANCE) {
|
||||
explanation = "Type parameter has an upper bound '" + result.getTypeRenderer().render(upperBound) + "'" +
|
||||
" that cannot be satisfied capturing 'in' projection";
|
||||
}
|
||||
else {
|
||||
explanation = "Only top level type projections can be captured";
|
||||
}
|
||||
result.text(newText().normal("'" + typeParameterWithCapturedConstraint.getName() + "'" +
|
||||
" cannot capture " +
|
||||
"'" + capturedTypeConstructor.getTypeProjection() + "'. " +
|
||||
"Only top level type projections can be captured"));
|
||||
explanation));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// !CHECK_TYPE
|
||||
|
||||
fun <T: Any> bar(a: Array<T>): Array<T?> = null!!
|
||||
|
||||
fun test1(a: Array<in Int>) {
|
||||
val r: Array<in Int?> = <!TYPE_INFERENCE_CANNOT_CAPTURE_TYPES!>bar<!>(a)
|
||||
<!TYPE_INFERENCE_CANNOT_CAPTURE_TYPES!>bar<!>(a)
|
||||
}
|
||||
|
||||
fun <T: Any> foo(l: Array<T>): Array<Array<T?>> = null!!
|
||||
|
||||
fun test2(a: Array<in Int>) {
|
||||
val r: Array<out Array<in Int?>> = <!TYPE_INFERENCE_CANNOT_CAPTURE_TYPES!>foo<!>(a)
|
||||
<!TYPE_INFERENCE_CANNOT_CAPTURE_TYPES!>foo<!>(a)
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package
|
||||
|
||||
internal fun </*0*/ T : kotlin.Any> bar(/*0*/ a: kotlin.Array<T>): kotlin.Array<T?>
|
||||
internal fun </*0*/ T : kotlin.Any> foo(/*0*/ l: kotlin.Array<T>): kotlin.Array<kotlin.Array<T?>>
|
||||
internal fun test1(/*0*/ a: kotlin.Array<in kotlin.Int>): kotlin.Unit
|
||||
internal fun test2(/*0*/ a: kotlin.Array<in kotlin.Int>): kotlin.Unit
|
||||
@@ -5094,6 +5094,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/capturedTypes"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("cannotCaptureInProjection.kt")
|
||||
public void testCannotCaptureInProjection() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/capturedTypes/cannotCaptureInProjection.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("captureForNullableTypes.kt")
|
||||
public void testCaptureForNullableTypes() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/capturedTypes/captureForNullableTypes.kt");
|
||||
|
||||
+6
-1
@@ -379,7 +379,12 @@ public class ConstraintSystemImpl : ConstraintSystem {
|
||||
constrainingTypeProjection: TypeProjection,
|
||||
constraintPosition: ConstraintPosition
|
||||
) {
|
||||
val typeBounds = getTypeBounds(parameterType)
|
||||
val typeVariable = getMyTypeVariable(parameterType)!!
|
||||
if (!KotlinBuiltIns.isNullableAny(typeVariable.getUpperBoundsAsType())
|
||||
&& constrainingTypeProjection.getProjectionKind() == Variance.IN_VARIANCE) {
|
||||
cannotCaptureTypesError = true
|
||||
}
|
||||
val typeBounds = getTypeBounds(typeVariable)
|
||||
val typeProjection = if (parameterType.isMarkedNullable()) {
|
||||
TypeProjectionImpl(constrainingTypeProjection.getProjectionKind(), TypeUtils.makeNotNullable(constrainingTypeProjection.getType()))
|
||||
}
|
||||
|
||||
@@ -878,6 +878,10 @@ public class KotlinBuiltIns {
|
||||
return isConstructedFromGivenClass(type, FQ_NAMES.any);
|
||||
}
|
||||
|
||||
public static boolean isNullableAny(@NotNull JetType type) {
|
||||
return isAnyOrNullableAny(type) && type.isMarkedNullable();
|
||||
}
|
||||
|
||||
public static boolean isUnit(@NotNull JetType type) {
|
||||
return isNotNullConstructedFromGivenClass(type, FQ_NAMES.unit);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user