KT-3184 Type inference seems partially broken
#KT-3184 fixed
This commit is contained in:
+41
-5
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.jet.lang.resolve.calls.inference;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -177,15 +178,29 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
assert subjectType != TypeUtils.NO_EXPECTED_TYPE : "Subject type shouldn't be NO_EXPECTED_TYPE (in position " + constraintPosition + " )";
|
||||
if (ErrorUtils.isErrorType(subjectType)) return;
|
||||
|
||||
DeclarationDescriptor subjectTypeDescriptor = subjectType.getConstructor().getDeclarationDescriptor();
|
||||
|
||||
KotlinBuiltIns kotlinBuiltIns = KotlinBuiltIns.getInstance();
|
||||
if (constrainingType == PLACEHOLDER_FUNCTION_TYPE) {
|
||||
if (!KotlinBuiltIns.getInstance().isFunctionOrExtensionFunctionType(subjectType)) {
|
||||
if (!kotlinBuiltIns.isFunctionOrExtensionFunctionType(subjectType)) {
|
||||
if (subjectTypeDescriptor instanceof TypeParameterDescriptor && typeParameterConstraints.get(subjectTypeDescriptor) != null) {
|
||||
// a constraint binds type parameter and any function type, so there is no new info and no error
|
||||
return;
|
||||
}
|
||||
errorConstraintPositions.add(constraintPosition);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// todo temporary hack
|
||||
// function literal without declaring receiver type { x -> ... }
|
||||
// can be considered as extension function if one is expected
|
||||
// (special type constructor for function/ extension function should be introduced like PLACEHOLDER_FUNCTION_TYPE)
|
||||
if (constraintKind == SUB_TYPE && kotlinBuiltIns.isFunctionType(constrainingType) && kotlinBuiltIns.isExtensionFunctionType(subjectType)) {
|
||||
constrainingType = createCorrespondingExtensionFunctionType(constrainingType, DONT_CARE);
|
||||
}
|
||||
|
||||
DeclarationDescriptor constrainingTypeDescriptor = constrainingType.getConstructor().getDeclarationDescriptor();
|
||||
DeclarationDescriptor subjectTypeDescriptor = subjectType.getConstructor().getDeclarationDescriptor();
|
||||
|
||||
if (subjectTypeDescriptor instanceof TypeParameterDescriptor) {
|
||||
TypeParameterDescriptor typeParameter = (TypeParameterDescriptor) subjectTypeDescriptor;
|
||||
@@ -204,7 +219,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
if (constrainingTypeDescriptor instanceof TypeParameterDescriptor) {
|
||||
assert typeParameterConstraints.get(constrainingTypeDescriptor) == null : "Constraining type contains type variable " + constrainingTypeDescriptor.getName();
|
||||
}
|
||||
if (constraintKind == SUB_TYPE && KotlinBuiltIns.getInstance().isNothingOrNullableNothing(constrainingType)) {
|
||||
if (constraintKind == SUB_TYPE && kotlinBuiltIns.isNothingOrNullableNothing(constrainingType)) {
|
||||
// following constraints are always true:
|
||||
// 'Nothing' is a subtype of any type
|
||||
if (!constrainingType.isNullable()) return;
|
||||
@@ -217,7 +232,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
}
|
||||
switch (constraintKind) {
|
||||
case SUB_TYPE: {
|
||||
if (KotlinBuiltIns.getInstance().isNothingOrNullableNothing(constrainingType)) break;
|
||||
if (kotlinBuiltIns.isNothingOrNullableNothing(constrainingType)) break;
|
||||
JetType correspondingSupertype = TypeCheckingProcedure.findCorrespondingSupertype(constrainingType, subjectType);
|
||||
if (correspondingSupertype != null) {
|
||||
constrainingType = correspondingSupertype;
|
||||
@@ -225,7 +240,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
break;
|
||||
}
|
||||
case SUPER_TYPE: {
|
||||
if (KotlinBuiltIns.getInstance().isNothingOrNullableNothing(subjectType)) break;
|
||||
if (kotlinBuiltIns.isNothingOrNullableNothing(subjectType)) break;
|
||||
JetType correspondingSupertype = TypeCheckingProcedure.findCorrespondingSupertype(subjectType, constrainingType);
|
||||
if (correspondingSupertype != null) {
|
||||
subjectType = correspondingSupertype;
|
||||
@@ -388,4 +403,25 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
public TypeSubstitutor getCurrentSubstitutor() {
|
||||
return currentSubstitutor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JetType createCorrespondingExtensionFunctionType(@NotNull JetType functionType, @NotNull JetType receiverType) {
|
||||
assert KotlinBuiltIns.getInstance().isFunctionType(functionType);
|
||||
|
||||
List<TypeProjection> typeArguments = functionType.getArguments();
|
||||
assert !typeArguments.isEmpty();
|
||||
|
||||
List<JetType> arguments = Lists.newArrayList();
|
||||
// excluding the last type argument of the function type, which is the return type
|
||||
int index = 0;
|
||||
int lastIndex = typeArguments.size() - 1;
|
||||
for (TypeProjection typeArgument : typeArguments) {
|
||||
if (index < lastIndex) {
|
||||
arguments.add(typeArgument.getType());
|
||||
}
|
||||
index++;
|
||||
}
|
||||
JetType returnType = typeArguments.get(lastIndex).getType();
|
||||
return KotlinBuiltIns.getInstance().getFunctionType(functionType.getAnnotations(), receiverType, arguments, returnType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
//KT-3184 Type inference seems partially broken
|
||||
package a
|
||||
|
||||
import java.util.HashMap
|
||||
|
||||
private fun <T> test(value: T, extf: String.(value: T)->Unit) {
|
||||
"".extf(value)
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
test(1, {(value) -> println(value)})
|
||||
}
|
||||
|
||||
fun tests() {
|
||||
val dict = HashMap<String, (String) -> Unit>()
|
||||
dict["0"] = { str -> println(str) }
|
||||
dict["1"] = { println(it) }
|
||||
|
||||
dict.set("1", { println(it) })
|
||||
dict["1"] = { r -> println(r) }
|
||||
}
|
||||
|
||||
// from standard library
|
||||
fun <K, V> MutableMap<K, V>.set(key : K, value : V) : V<!BASE_WITH_NULLABLE_UPPER_BOUND!>?<!> = this.put(key, value)
|
||||
|
||||
fun println(message : Any?) = System.out.println(message)
|
||||
@@ -2036,6 +2036,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
doTest("compiler/testData/diagnostics/tests/inference/kt1293.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt3184.kt")
|
||||
public void testKt3184() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/inference/kt3184.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt619.kt")
|
||||
public void testKt619() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/inference/kt619.kt");
|
||||
|
||||
Reference in New Issue
Block a user