Report an error on dynamic types used as supertypes or upper bounds
This commit is contained in:
@@ -149,6 +149,7 @@ public interface Errors {
|
||||
DiagnosticFactory0<JetTypeReference> FINAL_SUPERTYPE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<JetTypeReference> SINGLETON_IN_SUPERTYPE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<JetNullableType> NULLABLE_SUPERTYPE = DiagnosticFactory0.create(ERROR, NULLABLE_TYPE);
|
||||
DiagnosticFactory0<JetTypeReference> DYNAMIC_SUPERTYPE = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
// Trait-specific
|
||||
|
||||
@@ -196,6 +197,7 @@ public interface Errors {
|
||||
|
||||
DiagnosticFactory1<JetTypeReference, JetType> FINAL_UPPER_BOUND = DiagnosticFactory1.create(WARNING);
|
||||
DiagnosticFactory1<JetTypeReference, JetType> FINAL_CLASS_OBJECT_UPPER_BOUND = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory0<JetTypeReference> DYNAMIC_UPPER_BOUND = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory1<JetNamedDeclaration, TypeParameterDescriptor> CONFLICTING_UPPER_BOUNDS =
|
||||
DiagnosticFactory1.create(ERROR, DECLARATION_NAME);
|
||||
|
||||
+2
@@ -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. " +
|
||||
|
||||
@@ -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<JetTypeReference> jetTypeArguments = typeElement.getTypeArgumentsAsTypes();
|
||||
|
||||
// A type reference from Kotlin code can yield a flexible type only if it's `ft<T1, T2>`, 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<T1, T2>, but was: "
|
||||
+ JetPsiUtil.getElementTextWithContext(typeReference);
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// MODULE[js]: m1
|
||||
// FILE: k.kt
|
||||
|
||||
trait Tr : <!DYNAMIC_SUPERTYPE!>dynamic<!>
|
||||
|
||||
fun <T: <!DYNAMIC_UPPER_BOUND!>dynamic<!>> foo() {}
|
||||
|
||||
class C<T> where T : <!DYNAMIC_UPPER_BOUND!>dynamic<!>
|
||||
@@ -0,0 +1,16 @@
|
||||
package
|
||||
|
||||
internal fun </*0*/ T : dynamic> foo(): kotlin.Unit
|
||||
|
||||
internal final class C</*0*/ T : dynamic> {
|
||||
public constructor C</*0*/ T : dynamic>()
|
||||
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
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user