KT-385 type inference does not work properly
KT-109 Good code is red: type arguments are not inferred KT-441 Exception in type inference when multiple overloads accepting an integer literal are accessible
This commit is contained in:
@@ -442,7 +442,7 @@ public class CallResolver {
|
||||
}
|
||||
|
||||
ConstraintSystemSolution solution = constraintSystem.solve();
|
||||
if (solution.isSuccessful()) {
|
||||
if (solution.getStatus().isSuccessful()) {
|
||||
D substitute = (D) candidate.substitute(solution.getSubstitutor());
|
||||
assert substitute != null;
|
||||
replaceValueParametersWithSubstitutedOnes(candidateCall, substitute);
|
||||
|
||||
+52
-14
@@ -269,8 +269,10 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
|
||||
private void addSubtypingConstraintOnTypeValues(TypeValue typeValueForLower, TypeValue typeValueForUpper) {
|
||||
println(typeValueForLower + " :< " + typeValueForUpper);
|
||||
typeValueForLower.getUpperBounds().add(typeValueForUpper);
|
||||
typeValueForUpper.getLowerBounds().add(typeValueForLower);
|
||||
if (typeValueForLower != typeValueForUpper) {
|
||||
typeValueForLower.getUpperBounds().add(typeValueForUpper);
|
||||
typeValueForUpper.getLowerBounds().add(typeValueForLower);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -286,7 +288,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
KnownType knownBoundType = (KnownType) upperBound;
|
||||
boolean ok = constraintExpander.run(jetType, knownBoundType.getType());
|
||||
if (!ok) {
|
||||
return new Solution(true);
|
||||
return new Solution().registerError("Mismatch while expanding constraints");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -314,7 +316,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
}
|
||||
|
||||
// Find inconsistencies
|
||||
Solution solution = new Solution(false);
|
||||
Solution solution = new Solution();
|
||||
|
||||
for (UnknownType unknownType : unknownTypes.values()) {
|
||||
check(unknownType, solution);
|
||||
@@ -337,20 +339,33 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
for (TypeValue upperBound : typeValue.getUpperBounds()) {
|
||||
JetType boundingType = solution.getSubstitutor().substitute(upperBound.getValue().getType(), Variance.INVARIANT);
|
||||
if (!typeChecker.isSubtypeOf(type, boundingType)) { // TODO
|
||||
solution.registerError();
|
||||
solution.registerError("Constraint violation: " + type + " is not a subtype of " + boundingType);
|
||||
println("Constraint violation: " + type + " :< " + boundingType);
|
||||
}
|
||||
}
|
||||
for (TypeValue lowerBound : typeValue.getLowerBounds()) {
|
||||
JetType boundingType = solution.getSubstitutor().substitute(lowerBound.getValue().getType(), Variance.INVARIANT);
|
||||
if (!typeChecker.isSubtypeOf(boundingType, type)) {
|
||||
solution.registerError();
|
||||
solution.registerError("Constraint violation: " + boundingType + " is not a subtype of " + type);
|
||||
println("Constraint violation: " + boundingType + " :< " + type);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (LoopInTypeVariableConstraintsException e) {
|
||||
solution.registerError();
|
||||
println("-------------------------------------------------------------------");
|
||||
for (Map.Entry<TypeParameterDescriptor, UnknownType> entry : unknownTypes.entrySet()) {
|
||||
println("Unknown: " + entry.getKey());
|
||||
UnknownType unknownType = entry.getValue();
|
||||
println("Lower bounds: ");
|
||||
for (TypeValue lowerBound : unknownType.getLowerBounds()) {
|
||||
println(" " + lowerBound);
|
||||
}
|
||||
println("Upper bounds: ");
|
||||
for (TypeValue lowerBound : unknownType.getUpperBounds()) {
|
||||
println(" " + lowerBound);
|
||||
}
|
||||
}
|
||||
solution.registerError("[TODO] Loop in constraints");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@@ -369,6 +384,25 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
}
|
||||
}
|
||||
|
||||
private static class Error implements SolutionStatus {
|
||||
|
||||
private final String message;
|
||||
|
||||
private Error(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuccessful() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
public class Solution implements ConstraintSystemSolution {
|
||||
private final TypeSubstitutor typeSubstitutor = TypeSubstitutor.create(new TypeSubstitutor.TypeSubstitution() {
|
||||
@Override
|
||||
@@ -388,19 +422,22 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
private boolean failed;
|
||||
|
||||
public Solution(boolean failed) {
|
||||
this.failed = failed;
|
||||
private SolutionStatus status;
|
||||
|
||||
public Solution() {
|
||||
this.status = SolutionStatus.SUCCESS;
|
||||
}
|
||||
|
||||
private void registerError() {
|
||||
failed = true;
|
||||
private Solution registerError(String message) {
|
||||
status = new Error(message);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public boolean isSuccessful() {
|
||||
return !failed;
|
||||
public SolutionStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -409,6 +446,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
return value == null ? null : value.getType();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TypeSubstitutor getSubstitutor() {
|
||||
return typeSubstitutor;
|
||||
|
||||
+4
-1
@@ -1,5 +1,6 @@
|
||||
package org.jetbrains.jet.lang.types.inference;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
@@ -9,8 +10,10 @@ import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface ConstraintSystemSolution {
|
||||
boolean isSuccessful();
|
||||
@NotNull
|
||||
SolutionStatus getStatus();
|
||||
|
||||
@NotNull
|
||||
TypeSubstitutor getSubstitutor();
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.jetbrains.jet.lang.types.inference;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface SolutionStatus {
|
||||
SolutionStatus SUCCESS = new SolutionStatus() {
|
||||
@Override
|
||||
public boolean isSuccessful() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
boolean isSuccessful();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// KT-385 type inference does not work properly`
|
||||
// KT-109 Good code is red: type arguments are not inferred
|
||||
// KT-441 Exception in type inference when multiple overloads accepting an integer literal are accessible
|
||||
|
||||
import java.util.*
|
||||
|
||||
fun <T> Iterator<T>.foreach(operation: fun(element: T) : Unit) : Unit = while(hasNext) operation(next())
|
||||
|
||||
fun <T> Iterator<T>.foreach(operation: fun(index: Int, element: T) : Unit) : Unit {
|
||||
var k = 0
|
||||
while(hasNext)
|
||||
operation(k++, next())
|
||||
}
|
||||
|
||||
fun <T> Iterable<T>.foreach(operation: fun(element: T) : Unit) : Unit = iterator() foreach operation
|
||||
|
||||
fun <T> Iterable<T>.foreach(operation: fun(index: Int, element: T) : Unit) : Unit = iterator() foreach operation
|
||||
|
||||
fun box() : String {
|
||||
return generic_invoker( { () : String => "OK"} )
|
||||
}
|
||||
|
||||
fun <T> generic_invoker(gen : fun () : T) : T {
|
||||
return gen()
|
||||
}
|
||||
|
||||
fun println(message : Int) { System.out?.println(message) }
|
||||
fun println(message : Long) { System.out?.println(message) }
|
||||
inline fun run<T>(body : fun() : T) : T = body()
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
|
||||
println(run { 1 })
|
||||
}
|
||||
Reference in New Issue
Block a user