diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java index 9d17491bd96..1db48c9188c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java @@ -149,6 +149,7 @@ public interface Errors { DiagnosticFactory0 FINAL_SUPERTYPE = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 SINGLETON_IN_SUPERTYPE = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 NULLABLE_SUPERTYPE = DiagnosticFactory0.create(ERROR, NULLABLE_TYPE); + DiagnosticFactory0 DYNAMIC_SUPERTYPE = DiagnosticFactory0.create(ERROR); // Trait-specific @@ -196,6 +197,7 @@ public interface Errors { DiagnosticFactory1 FINAL_UPPER_BOUND = DiagnosticFactory1.create(WARNING); DiagnosticFactory1 FINAL_CLASS_OBJECT_UPPER_BOUND = DiagnosticFactory1.create(ERROR); + DiagnosticFactory0 DYNAMIC_UPPER_BOUND = DiagnosticFactory0.create(ERROR); DiagnosticFactory1 CONFLICTING_UPPER_BOUNDS = DiagnosticFactory1.create(ERROR, DECLARATION_NAME); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java index 1bdd87380b4..85c0a8050c1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java @@ -322,6 +322,7 @@ public class DefaultErrorMessages { MAP.put(UPPER_BOUND_VIOLATED, "Type argument is not within its bounds: should be subtype of ''{0}''", RENDER_TYPE, RENDER_TYPE); MAP.put(FINAL_CLASS_OBJECT_UPPER_BOUND, "''{0}'' is a final type, and thus a class object cannot extend it", RENDER_TYPE); MAP.put(FINAL_UPPER_BOUND, "''{0}'' is a final type, and thus a value of the type parameter is predetermined", RENDER_TYPE); + MAP.put(DYNAMIC_UPPER_BOUND, "Dynamic type can not be used as an upper bound"); MAP.put(USELESS_ELVIS, "Elvis operator (?:) always returns the left operand of non-nullable type {0}", RENDER_TYPE); MAP.put(CONFLICTING_UPPER_BOUNDS, "Upper bounds of {0} have empty intersection", NAME); MAP.put(CONFLICTING_CLASS_OBJECT_UPPER_BOUNDS, "Class object upper bounds of {0} have empty intersection", NAME); @@ -365,6 +366,7 @@ public class DefaultErrorMessages { MAP.put(ANONYMOUS_INITIALIZER_IN_TRAIT, "Anonymous initializers are not allowed in traits"); MAP.put(NULLABLE_SUPERTYPE, "A supertype cannot be nullable"); + MAP.put(DYNAMIC_SUPERTYPE, "A supertype cannot be dynamic"); MAP.put(REDUNDANT_NULLABLE, "Redundant '?'"); MAP.put(BASE_WITH_NULLABLE_UPPER_BOUND, "''{0}'' has a nullable upper bound. " + "This means that a value of this type may be null. " + diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java index 6a0d676720b..9c6723a7822 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java @@ -238,9 +238,15 @@ public class DescriptorResolver { for (JetDelegationSpecifier delegationSpecifier : delegationSpecifiers) { JetTypeReference typeReference = delegationSpecifier.getTypeReference(); if (typeReference != null) { - result.add(resolver.resolveType(extensibleScope, typeReference, trace, checkBounds)); - JetTypeElement bareSuperType = checkNullableSupertypeAndStripQuestionMarks(trace, typeReference.getTypeElement()); - checkProjectionsInImmediateArguments(trace, bareSuperType); + JetType supertype = resolver.resolveType(extensibleScope, typeReference, trace, checkBounds); + if (TypesPackage.isDynamic(supertype)) { + trace.report(DYNAMIC_SUPERTYPE.on(typeReference)); + } + else { + result.add(supertype); + JetTypeElement bareSuperType = checkNullableSupertypeAndStripQuestionMarks(trace, typeReference.getTypeElement()); + checkProjectionsInImmediateArguments(trace, bareSuperType); + } } else { result.add(ErrorUtils.createErrorType("No type reference")); @@ -791,6 +797,9 @@ public class DescriptorResolver { trace.report(FINAL_UPPER_BOUND.on(upperBound, upperBoundType)); } } + if (TypesPackage.isDynamic(upperBoundType)) { + trace.report(DYNAMIC_UPPER_BOUND.on(upperBound)); + } } @NotNull @@ -1366,7 +1375,7 @@ public class DescriptorResolver { List jetTypeArguments = typeElement.getTypeArgumentsAsTypes(); // A type reference from Kotlin code can yield a flexible type only if it's `ft`, whose bounds should not be checked - if (TypesPackage.isFlexible(type)) { + if (TypesPackage.isFlexible(type) && !TypesPackage.isDynamic(type)) { assert jetTypeArguments.size() == 2 : "Flexible type cannot be denoted in Kotlin otherwise than as ft, but was: " + JetPsiUtil.getElementTextWithContext(typeReference); diff --git a/compiler/testData/diagnostics/tests/dynamicTypes/supertypesAndBounds.kt b/compiler/testData/diagnostics/tests/dynamicTypes/supertypesAndBounds.kt new file mode 100644 index 00000000000..8e4a0c6dae8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/dynamicTypes/supertypesAndBounds.kt @@ -0,0 +1,8 @@ +// MODULE[js]: m1 +// FILE: k.kt + +trait Tr : dynamic + +fun dynamic> foo() {} + +class C where T : dynamic \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/dynamicTypes/supertypesAndBounds.txt b/compiler/testData/diagnostics/tests/dynamicTypes/supertypesAndBounds.txt new file mode 100644 index 00000000000..fa154ba21ac --- /dev/null +++ b/compiler/testData/diagnostics/tests/dynamicTypes/supertypesAndBounds.txt @@ -0,0 +1,16 @@ +package + +internal fun foo(): kotlin.Unit + +internal final class C { + public constructor C() + 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 +} + +internal trait Tr { + 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/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index cbf8e2306eb..6961b0ce177 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -3818,6 +3818,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("supertypesAndBounds.kt") + public void testSupertypesAndBounds() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/dynamicTypes/supertypesAndBounds.kt"); + doTest(fileName); + } + @TestMetadata("unsupported.kt") public void testUnsupported() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/dynamicTypes/unsupported.kt"); diff --git a/spec-docs/dynamic-types.md b/spec-docs/dynamic-types.md index 6f9b5e85845..0a210dcdc65 100644 --- a/spec-docs/dynamic-types.md +++ b/spec-docs/dynamic-types.md @@ -31,7 +31,7 @@ fun jsFun(p: dynamic): dynamic - `lub(T, dynamic) = dynamic` - ??? `glb(T, dynamic) = T` - `dynamic` can't be substituted for reified parameters of function/constructor calls (this means that it's not possible to create an array of `dynamic`) -- `dynamic` can't be used as a supertype or upper bound for a tpe parameter +- `dynamic` can't be used as a supertype or upper bound for a type parameter - `dynamic` is less specific than any other type ## Syntax