type inference with functional literal params changed
if there are function literals without declared parameter types, try adding constraint with current substituted result first (known type parameters), if there is error, try adding constraint with 'dont_care' substitution
This commit is contained in:
@@ -347,6 +347,9 @@ public class CallResolver {
|
||||
constraintSystem.addSubtypingConstraint(descriptor.getReturnType(), context.expectedType,
|
||||
ConstraintPosition.EXPECTED_TYPE_POSITION);
|
||||
|
||||
TypeSubstitutor substituteDontCare = ConstraintSystemWithPriorities
|
||||
.makeConstantSubstitutor(resolvedCall.getCandidateDescriptor().getTypeParameters(), ConstraintSystemImpl.DONT_CARE);
|
||||
|
||||
// constraints for function literals
|
||||
// Value parameters
|
||||
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : resolvedCall.getValueArguments().entrySet()) {
|
||||
@@ -356,8 +359,15 @@ public class CallResolver {
|
||||
for (ValueArgument valueArgument : resolvedValueArgument.getArguments()) {
|
||||
if (!JetPsiUtil.isFunctionLiteralWithoutDeclaredParameterTypes(valueArgument.getArgumentExpression())) continue;
|
||||
|
||||
ConstraintSystem systemWithCurrentSubstitution = constraintSystem.copy();
|
||||
addConstraintForValueArgument(valueArgument, valueParameterDescriptor, constraintSystem.getCurrentSubstitutor(),
|
||||
constraintSystem, context);
|
||||
systemWithCurrentSubstitution, context);
|
||||
if (systemWithCurrentSubstitution.hasContradiction() || systemWithCurrentSubstitution.hasErrorInConstrainingTypes()) {
|
||||
addConstraintForValueArgument(valueArgument, valueParameterDescriptor, substituteDontCare, constraintSystem, context);
|
||||
}
|
||||
else {
|
||||
constraintSystem = systemWithCurrentSubstitution;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -753,7 +763,7 @@ public class CallResolver {
|
||||
|
||||
|
||||
// Solution
|
||||
if (!constraintsSystem.hasTypeConstructorMismatch() && !constraintsSystem.hasConflictingConstraints()) { //no contradiction
|
||||
if (!constraintsSystem.hasContradiction()) {
|
||||
candidateCall.setHasUnknownTypeParameters(true);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
+7
@@ -64,6 +64,11 @@ public interface ConstraintSystem {
|
||||
*/
|
||||
boolean isSuccessful();
|
||||
|
||||
/**
|
||||
* Return <tt>true</tt> if constraint system has no contradiction (it can be not successful because of the lack of information for a type variable).
|
||||
*/
|
||||
boolean hasContradiction();
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if type constraints for some type variable are contradicting. <p/>
|
||||
*
|
||||
@@ -133,4 +138,6 @@ public interface ConstraintSystem {
|
||||
*/
|
||||
@NotNull
|
||||
TypeSubstitutor getCurrentSubstitutor();
|
||||
|
||||
ConstraintSystem copy();
|
||||
}
|
||||
|
||||
+16
-3
@@ -105,6 +105,16 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
typeParameterConstraints.put(typeVariable, new TypeConstraintsImpl(positionVariance));
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public ConstraintSystem copy() {
|
||||
ConstraintSystemImpl newConstraintSystem = new ConstraintSystemImpl();
|
||||
newConstraintSystem.typeParameterConstraints.putAll(typeParameterConstraints);
|
||||
newConstraintSystem.errorConstraintPositions.addAll(errorConstraintPositions);
|
||||
newConstraintSystem.hasErrorInConstrainingTypes = hasErrorInConstrainingTypes;
|
||||
return newConstraintSystem;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConstraintSystem replaceTypeVariables(@NotNull Function<TypeParameterDescriptor, TypeParameterDescriptor> typeVariablesMap) {
|
||||
ConstraintSystemImpl newConstraintSystem = new ConstraintSystemImpl();
|
||||
@@ -116,9 +126,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
assert newTypeParameter != null;
|
||||
newConstraintSystem.typeParameterConstraints.put(newTypeParameter, typeConstraints);
|
||||
}
|
||||
for (ConstraintPosition constraintPosition : errorConstraintPositions) {
|
||||
newConstraintSystem.errorConstraintPositions.add(constraintPosition);
|
||||
}
|
||||
newConstraintSystem.errorConstraintPositions.addAll(errorConstraintPositions);
|
||||
newConstraintSystem.hasErrorInConstrainingTypes = hasErrorInConstrainingTypes;
|
||||
return newConstraintSystem;
|
||||
}
|
||||
@@ -221,6 +229,11 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
return !hasTypeConstructorMismatch() && !hasUnknownParameters() && !hasConflictingConstraints();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasContradiction() {
|
||||
return hasTypeConstructorMismatch() || hasConflictingConstraints();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasConflictingConstraints() {
|
||||
for (TypeParameterDescriptor typeParameter : typeParameterConstraints.keySet()) {
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package n
|
||||
|
||||
//+JDK
|
||||
import java.util.*
|
||||
|
||||
fun expected<T>(t: T, <!UNUSED_PARAMETER!>f<!>: () -> T) : T = t
|
||||
|
||||
fun test(arrayList: ArrayList<Int>, list: List<Int>) {
|
||||
val <!UNUSED_VARIABLE!>t<!> = expected(arrayList, { list.reverse() })
|
||||
}
|
||||
|
||||
fun <T> List<T>.reverse() : List<T> = this
|
||||
Reference in New Issue
Block a user