Fix for a cyclic generic upper bound for a class type parameter. A pair of tests.
This commit is contained in:
@@ -457,6 +457,20 @@ public class DescriptorResolver {
|
||||
}
|
||||
}
|
||||
|
||||
public JetType resolveTypeParameterExtendsBound(
|
||||
@NotNull TypeParameterDescriptor typeParameterDescriptor,
|
||||
@NotNull JetTypeReference extendsBound,
|
||||
JetScope scope,
|
||||
BindingTrace trace
|
||||
) {
|
||||
JetType type = typeResolver.resolveType(scope, extendsBound, trace, false);
|
||||
if (type.getConstructor().equals(typeParameterDescriptor.getTypeConstructor())) {
|
||||
trace.report(Errors.CYCLIC_GENERIC_UPPER_BOUND.on(extendsBound));
|
||||
type = ErrorUtils.createErrorType("Cyclic upper bound: " + type);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public void resolveGenericBounds(
|
||||
@NotNull JetTypeParameterListOwner declaration,
|
||||
@NotNull DeclarationDescriptor descriptor,
|
||||
@@ -476,11 +490,7 @@ public class DescriptorResolver {
|
||||
|
||||
JetTypeReference extendsBound = jetTypeParameter.getExtendsBound();
|
||||
if (extendsBound != null) {
|
||||
JetType type = typeResolver.resolveType(scope, extendsBound, trace, false);
|
||||
if (type.getConstructor().equals(typeParameterDescriptor.getTypeConstructor())) {
|
||||
trace.report(Errors.CYCLIC_GENERIC_UPPER_BOUND.on(extendsBound));
|
||||
type = ErrorUtils.createErrorType("Cyclic upper bound: " + type);
|
||||
}
|
||||
JetType type = resolveTypeParameterExtendsBound(typeParameterDescriptor, extendsBound, scope, trace);
|
||||
typeParameterDescriptor.addUpperBound(type);
|
||||
deferredUpperBoundCheckerTasks.add(new UpperBoundCheckerTask(extendsBound, type));
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ public class TypeResolver(
|
||||
if (baseType.isNullable() || innerType is JetNullableType || innerType is JetDynamicType) {
|
||||
c.trace.report(REDUNDANT_NULLABLE.on(nullableType))
|
||||
}
|
||||
else if (!baseType.isBare() && TypeUtils.hasNullableSuperType(baseType.getActualType())) {
|
||||
else if (c.checkBounds && !baseType.isBare() && TypeUtils.hasNullableSuperType(baseType.getActualType())) {
|
||||
c.trace.report(BASE_WITH_NULLABLE_UPPER_BOUND.on(nullableType, baseType.getActualType()))
|
||||
}
|
||||
result = baseType.makeNullable()
|
||||
|
||||
+5
-1
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.lazy.descriptors;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.descriptors.impl.AbstractLazyTypeParameterDescriptor;
|
||||
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||
import org.jetbrains.kotlin.lexer.JetTokens;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
@@ -26,6 +27,7 @@ import org.jetbrains.kotlin.resolve.DescriptorResolver;
|
||||
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
|
||||
import org.jetbrains.kotlin.resolve.lazy.LazyClassContext;
|
||||
import org.jetbrains.kotlin.resolve.lazy.LazyEntity;
|
||||
import org.jetbrains.kotlin.types.ErrorUtils;
|
||||
import org.jetbrains.kotlin.types.JetType;
|
||||
|
||||
import java.util.Set;
|
||||
@@ -66,7 +68,9 @@ public class LazyTypeParameterDescriptor extends AbstractLazyTypeParameterDescri
|
||||
|
||||
JetTypeReference extendsBound = jetTypeParameter.getExtendsBound();
|
||||
if (extendsBound != null) {
|
||||
upperBounds.add(resolveBoundType(extendsBound));
|
||||
JetType boundType = c.getDescriptorResolver().resolveTypeParameterExtendsBound(
|
||||
this, extendsBound, getContainingDeclaration().getScopeForClassHeaderResolution(), c.getTrace());
|
||||
upperBounds.add(boundType);
|
||||
}
|
||||
|
||||
resolveUpperBoundsFromWhereClause(upperBounds);
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
class MyClass<T: <!CYCLIC_GENERIC_UPPER_BOUND!>T?<!>>
|
||||
@@ -0,0 +1,8 @@
|
||||
package
|
||||
|
||||
internal final class MyClass</*0*/ T : [ERROR : Cyclic upper bound: T?]> {
|
||||
public constructor MyClass</*0*/ T : [ERROR : Cyclic upper bound: T?]>()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
class MyClass<T: <!CYCLIC_GENERIC_UPPER_BOUND!>T<!>>
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package
|
||||
|
||||
internal final class MyClass</*0*/ T : [ERROR : Cyclic upper bound: T]> {
|
||||
public constructor MyClass</*0*/ T : [ERROR : Cyclic upper bound: T]>()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -10260,6 +10260,18 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("itselfAsUpperBoundInClass.kt")
|
||||
public void testItselfAsUpperBoundInClass() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/regressions/itselfAsUpperBoundInClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("itselfAsUpperBoundInClassNotNull.kt")
|
||||
public void testItselfAsUpperBoundInClassNotNull() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/regressions/itselfAsUpperBoundInClassNotNull.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("itselfAsUpperBoundLocal.kt")
|
||||
public void testItselfAsUpperBoundLocal() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/regressions/itselfAsUpperBoundLocal.kt");
|
||||
|
||||
Reference in New Issue
Block a user