diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java index 6bbac29d8f4..8b139bded99 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java @@ -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)); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt index 8b2d1863b2e..d6436ddecc9 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt @@ -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() diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyTypeParameterDescriptor.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyTypeParameterDescriptor.java index 2ac33a31c48..2d6129f077e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyTypeParameterDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyTypeParameterDescriptor.java @@ -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); diff --git a/compiler/testData/diagnostics/tests/regressions/itselfAsUpperBoundInClass.kt b/compiler/testData/diagnostics/tests/regressions/itselfAsUpperBoundInClass.kt new file mode 100644 index 00000000000..7745a4f9972 --- /dev/null +++ b/compiler/testData/diagnostics/tests/regressions/itselfAsUpperBoundInClass.kt @@ -0,0 +1 @@ +class MyClassT?> \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/regressions/itselfAsUpperBoundInClass.txt b/compiler/testData/diagnostics/tests/regressions/itselfAsUpperBoundInClass.txt new file mode 100644 index 00000000000..b3dc9bfffd8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/regressions/itselfAsUpperBoundInClass.txt @@ -0,0 +1,8 @@ +package + +internal final class MyClass { + public constructor MyClass() + 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 +} diff --git a/compiler/testData/diagnostics/tests/regressions/itselfAsUpperBoundInClassNotNull.kt b/compiler/testData/diagnostics/tests/regressions/itselfAsUpperBoundInClassNotNull.kt new file mode 100644 index 00000000000..47ec80cc903 --- /dev/null +++ b/compiler/testData/diagnostics/tests/regressions/itselfAsUpperBoundInClassNotNull.kt @@ -0,0 +1 @@ +class MyClassT> \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/regressions/itselfAsUpperBoundInClassNotNull.txt b/compiler/testData/diagnostics/tests/regressions/itselfAsUpperBoundInClassNotNull.txt new file mode 100644 index 00000000000..ff4c5ac4e07 --- /dev/null +++ b/compiler/testData/diagnostics/tests/regressions/itselfAsUpperBoundInClassNotNull.txt @@ -0,0 +1,8 @@ +package + +internal final class MyClass { + public constructor MyClass() + 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 +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index f39ed158222..de4ce2d3559 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -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");