new Out<in T>().produce() returns Any?
This commit is contained in:
@@ -50,10 +50,12 @@ public class TypeSubstitutor {
|
||||
if (value != null) {
|
||||
assert constructor.getDeclarationDescriptor() instanceof TypeParameterDescriptor;
|
||||
|
||||
if (!allows(howThisTypeIsUsed, value.getProjectionKind())) {
|
||||
throw new SubstitutionException("!!" + value.toString());
|
||||
}
|
||||
return value.getType();
|
||||
return substitutionResult(substitutionContext, (TypeParameterDescriptor) constructor.getDeclarationDescriptor(), howThisTypeIsUsed, Variance.INVARIANT, value).getType();
|
||||
//
|
||||
// if (!allows(howThisTypeIsUsed, value.getProjectionKind())) {
|
||||
// throw new SubstitutionException("!!" + value.toString());
|
||||
// }
|
||||
// return value.getType();
|
||||
}
|
||||
|
||||
return specializeType(type, substitutionContext, howThisTypeIsUsed);
|
||||
@@ -96,19 +98,11 @@ public class TypeSubstitutor {
|
||||
if (projectionValue != null) {
|
||||
assert typeToSubstituteIn.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor;
|
||||
|
||||
JetType typeValue = projectionValue.getType();
|
||||
Variance projectionKindValue = projectionValue.getProjectionKind();
|
||||
|
||||
if (!allows(parameterVariance, passedProjectionKind)) {
|
||||
return TypeUtils.makeStarProjection( correspondingTypeParameter);
|
||||
return TypeUtils.makeStarProjection(correspondingTypeParameter);
|
||||
}
|
||||
|
||||
if (!allows(effectiveContextVariance, projectionKindValue)) {
|
||||
throw new SubstitutionException(""); // TODO : error message
|
||||
}
|
||||
|
||||
Variance effectiveProjectionKindValue = passedProjectionKind == Variance.INVARIANT ? projectionKindValue : passedProjectionKind;
|
||||
return new TypeProjection(effectiveProjectionKindValue, specializeType(typeValue, substitutionContext, effectiveContextVariance));
|
||||
return substitutionResult(substitutionContext, correspondingTypeParameter, effectiveContextVariance, passedProjectionKind, projectionValue);
|
||||
}
|
||||
return new TypeProjection(
|
||||
passedProjectionKind,
|
||||
@@ -118,6 +112,51 @@ public class TypeSubstitutor {
|
||||
effectiveContextVariance));
|
||||
}
|
||||
|
||||
private TypeProjection substitutionResult(
|
||||
Map<TypeConstructor, TypeProjection> substitutionContext,
|
||||
TypeParameterDescriptor correspondingTypeParameter,
|
||||
Variance effectiveContextVariance,
|
||||
Variance passedProjectionKind,
|
||||
TypeProjection value) throws SubstitutionException {
|
||||
Variance projectionKindValue = value.getProjectionKind();
|
||||
JetType typeValue = value.getType();
|
||||
Variance effectiveProjectionKindValue = asymmetricOr(passedProjectionKind, projectionKindValue);
|
||||
JetType effectiveTypeValue;
|
||||
switch (effectiveContextVariance) {
|
||||
case INVARIANT:
|
||||
effectiveProjectionKindValue = projectionKindValue;
|
||||
effectiveTypeValue = typeValue;
|
||||
break;
|
||||
case IN_VARIANCE:
|
||||
if (projectionKindValue == Variance.OUT_VARIANCE) {
|
||||
throw new SubstitutionException(""); // TODO
|
||||
// effectiveProjectionKindValue = Variance.INVARIANT;
|
||||
// effectiveTypeValue = JetStandardClasses.getNothingType();
|
||||
}
|
||||
else {
|
||||
effectiveTypeValue = typeValue;
|
||||
}
|
||||
break;
|
||||
case OUT_VARIANCE:
|
||||
if (projectionKindValue == Variance.IN_VARIANCE) {
|
||||
effectiveProjectionKindValue = Variance.INVARIANT;
|
||||
effectiveTypeValue = correspondingTypeParameter.getBoundsAsType();
|
||||
}
|
||||
else {
|
||||
effectiveTypeValue = typeValue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException(effectiveContextVariance.toString());
|
||||
}
|
||||
|
||||
// if (!allows(effectiveContextVariance, projectionKindValue)) {
|
||||
// throw new SubstitutionException(""); // TODO : error message
|
||||
// }
|
||||
//
|
||||
return new TypeProjection(effectiveProjectionKindValue, specializeType(effectiveTypeValue, substitutionContext, effectiveContextVariance));
|
||||
}
|
||||
|
||||
private static Variance asymmetricOr(Variance a, Variance b) {
|
||||
return a == Variance.INVARIANT ? b : a;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import java.util.List;
|
||||
*/
|
||||
public class DescriptorUtil {
|
||||
public static String renderPresentableText(DeclarationDescriptor declarationDescriptor) {
|
||||
if (declarationDescriptor == null) return "<null>";
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
declarationDescriptor.accept(
|
||||
new DeclarationDescriptorVisitor<Void, StringBuilder>() {
|
||||
|
||||
@@ -34,11 +34,11 @@ fun testInOut() {
|
||||
|
||||
new Out<Int>().`Out.f`f()
|
||||
(return : Out<out Int>).`Out.f`f()
|
||||
(return : Out<in Int>).`!`f()
|
||||
(return : Out<in Int>).`Out.f`f()
|
||||
(return : Out<*>).`Out.f`f()
|
||||
|
||||
new Inv<Int>().`Inv.f`f(1)
|
||||
(return : Inv<in Int>).`!`f(1)
|
||||
(return : Inv<in Int>).`Inv.f`f(1)
|
||||
(return : Inv<out Int>).`!`f(1)
|
||||
(return : Inv<*>).`!`f(1)
|
||||
|
||||
@@ -48,7 +48,7 @@ fun testInOut() {
|
||||
(return : Inv<*>).`!`inf(1)
|
||||
|
||||
new Inv<Int>().`Inv.outf`outf()
|
||||
(return : Inv<in Int>).`Inv.outf`outf()`:std::Any?`
|
||||
((return : Inv<in Int>).`Inv.outf`outf())`:std::Any`
|
||||
(return : Inv<out Int>).`Inv.outf`outf()
|
||||
(return : Inv<*>).`Inv.outf`outf()
|
||||
|
||||
|
||||
@@ -27,11 +27,12 @@ public class ExpectedResolveData {
|
||||
private final Map<Integer, String> positionToType = new HashMap<Integer, String>();
|
||||
private final Map<String, DeclarationDescriptor> nameToDescriptor;
|
||||
private final Map<String, PsiElement> nameToPsiElement;
|
||||
// private final Map<String, JetType> nameToType;
|
||||
|
||||
|
||||
public ExpectedResolveData(Map<String, DeclarationDescriptor> nameToDescriptor, Map<String, PsiElement> nameToPsiElement) {
|
||||
public ExpectedResolveData(Map<String, DeclarationDescriptor> nameToDescriptor, Map<String, PsiElement> nameToPsiElement/*, Map<String, JetType> nameToType*/) {
|
||||
this.nameToDescriptor = nameToDescriptor;
|
||||
this.nameToPsiElement = nameToPsiElement;
|
||||
// this.nameToType = nameToType;
|
||||
}
|
||||
|
||||
public void extractData(final Document document) {
|
||||
@@ -107,7 +108,18 @@ public class ExpectedResolveData {
|
||||
|
||||
if ("!".equals(name)) {
|
||||
JetReferenceExpression referenceExpression = PsiTreeUtil.getParentOfType(element, JetReferenceExpression.class);
|
||||
assertTrue("Must have been unresolved: " + referenceExpression.getText(), unresolvedReferences.contains(referenceExpression));
|
||||
JetExpression statement = referenceExpression;
|
||||
while (true) {
|
||||
PsiElement parent = statement.getParent();
|
||||
if (!(parent instanceof JetExpression)) break;
|
||||
if (parent instanceof JetBlockExpression) break;
|
||||
statement = (JetExpression) parent;
|
||||
}
|
||||
assertTrue(
|
||||
"Must have been unresolved: " + referenceExpression.getText() +
|
||||
" in " + statement.getText() +
|
||||
" but was resolved to " + DescriptorUtil.renderPresentableText(bindingContext.resolveReferenceExpression(referenceExpression)),
|
||||
unresolvedReferences.contains(referenceExpression));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -160,7 +172,8 @@ public class ExpectedResolveData {
|
||||
TypeConstructor expectedTypeConstructor;
|
||||
if (typeName.startsWith("std::")) {
|
||||
ClassDescriptor expectedClass = lib.getLibraryScope().getClass(typeName.substring(5));
|
||||
assertNotNull("Expected class not found: " + typeName);
|
||||
|
||||
assertNotNull("Expected class not found: " + typeName, expectedClass);
|
||||
expectedTypeConstructor = expectedClass.getTypeConstructor();
|
||||
} else {
|
||||
Integer declarationPosition = declarationToPosition.get(typeName);
|
||||
|
||||
@@ -333,7 +333,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
||||
assertType("new Props<out Int>().p", "Int");
|
||||
assertType("new Props<Properties>().p.p", "Int");
|
||||
|
||||
assertErrorType("(return : Props<in Int>).p");
|
||||
assertType("(return : Props<in Int>).p", "Any?");
|
||||
}
|
||||
|
||||
public void testOverloads() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user