Nullability of dynamic types
This commit is contained in:
@@ -199,8 +199,9 @@ public class TypeResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitNullableType(nullableType: JetNullableType) {
|
override fun visitNullableType(nullableType: JetNullableType) {
|
||||||
val baseType = resolveTypeElement(c, annotations, nullableType.getInnerType())
|
val innerType = nullableType.getInnerType()
|
||||||
if (baseType.isNullable()) {
|
val baseType = resolveTypeElement(c, annotations, innerType)
|
||||||
|
if (baseType.isNullable() || innerType is JetNullableType || innerType is JetDynamicType) {
|
||||||
c.trace.report(REDUNDANT_NULLABLE.on(nullableType))
|
c.trace.report(REDUNDANT_NULLABLE.on(nullableType))
|
||||||
}
|
}
|
||||||
else if (!baseType.isBare() && TypeUtils.hasNullableSuperType(baseType.getActualType())) {
|
else if (!baseType.isBare() && TypeUtils.hasNullableSuperType(baseType.getActualType())) {
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
// !CHECK_TYPE
|
||||||
|
|
||||||
|
// MODULE[js]: m1
|
||||||
|
// FILE: k.kt
|
||||||
|
|
||||||
|
fun foo(dn: dynamic<!REDUNDANT_NULLABLE!>?<!>, d: dynamic, dnn: dynamic<!REDUNDANT_NULLABLE!>?<!><!REDUNDANT_NULLABLE!>?<!>) {
|
||||||
|
dn.checkType { it : _<dynamic>}
|
||||||
|
dn.checkType { it : _<dynamic<!REDUNDANT_NULLABLE!>?<!>>}
|
||||||
|
d.checkType { it : _<dynamic>}
|
||||||
|
d.checkType { it : _<dynamic<!REDUNDANT_NULLABLE!>?<!>>}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
internal fun foo(/*0*/ dn: dynamic, /*1*/ d: dynamic): kotlin.Unit
|
||||||
@@ -3722,6 +3722,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nullable.kt")
|
||||||
|
public void testNullable() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/dynamicTypes/nullable.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("overloading.kt")
|
@TestMetadata("overloading.kt")
|
||||||
public void testOverloading() throws Exception {
|
public void testOverloading() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/dynamicTypes/overloading.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/dynamicTypes/overloading.kt");
|
||||||
|
|||||||
+1
-1
@@ -389,7 +389,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
|
|
||||||
// can be equal for the recursive invocations:
|
// can be equal for the recursive invocations:
|
||||||
// fun <T> foo(i: Int) : T { ... return foo(i); } => T <: T
|
// fun <T> foo(i: Int) : T { ... return foo(i); } => T <: T
|
||||||
if (JetTypeChecker.DEFAULT.equalTypes(subType, superType)) return;
|
if (isMyTypeVariable(subType) && isMyTypeVariable(superType) && JetTypeChecker.DEFAULT.equalTypes(subType, superType)) return;
|
||||||
|
|
||||||
assert !isMyTypeVariable(subType) || !isMyTypeVariable(superType) :
|
assert !isMyTypeVariable(subType) || !isMyTypeVariable(superType) :
|
||||||
"The constraint shouldn't contain different type variables on both sides: " + subType + " <: " + superType;
|
"The constraint shouldn't contain different type variables on both sides: " + subType + " <: " + superType;
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ object DynamicType : DelegatingFlexibleType(
|
|||||||
DynamicTypeCapabilities
|
DynamicTypeCapabilities
|
||||||
) {
|
) {
|
||||||
override fun getDelegate() = upperBound
|
override fun getDelegate() = upperBound
|
||||||
|
|
||||||
|
override fun isNullable() = false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun JetType.isDynamic(): Boolean = this.getCapability(javaClass<Dynamicity>()) != null
|
fun JetType.isDynamic(): Boolean = this.getCapability(javaClass<Dynamicity>()) != null
|
||||||
@@ -47,18 +49,20 @@ public object DynamicTypeCapabilities : FlexibleTypeCapabilities {
|
|||||||
override fun <T : TypeCapability> getCapability(capabilityClass: Class<T>, jetType: JetType, flexibility: Flexibility): T? {
|
override fun <T : TypeCapability> getCapability(capabilityClass: Class<T>, jetType: JetType, flexibility: Flexibility): T? {
|
||||||
if (capabilityClass.isAssignableFrom(javaClass<Impl>()))
|
if (capabilityClass.isAssignableFrom(javaClass<Impl>()))
|
||||||
[suppress("UNCHECKED_CAST")]
|
[suppress("UNCHECKED_CAST")]
|
||||||
return Impl(jetType, flexibility) as T
|
return Impl as T
|
||||||
else return null
|
else return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private class Impl(val type: JetType, val flexibility: Flexibility) : Dynamicity, Specificity {
|
private object Impl : Dynamicity, Specificity, NullAwareness {
|
||||||
|
|
||||||
private val lowerBound: JetType get() = flexibility.lowerBound
|
|
||||||
private val upperBound: JetType get() = flexibility.upperBound
|
|
||||||
|
|
||||||
override fun getSpecificityRelationTo(otherType: JetType): Specificity.Relation {
|
override fun getSpecificityRelationTo(otherType: JetType): Specificity.Relation {
|
||||||
return if (!otherType.isDynamic()) Specificity.Relation.LESS_SPECIFIC else Specificity.Relation.DONT_KNOW
|
return if (!otherType.isDynamic()) Specificity.Relation.LESS_SPECIFIC else Specificity.Relation.DONT_KNOW
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun makeNullableAsSpecified(nullable: Boolean): JetType {
|
||||||
|
// Nullability has no effect on dynamics
|
||||||
|
return DynamicType
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user