[FIR] Fix creating DefinitelyNotNullTypes

Also fix substitutions to them
This commit is contained in:
Dmitriy Novozhilov
2020-01-27 16:59:08 +03:00
parent 4303cd2fc7
commit 57a1342aac
28 changed files with 117 additions and 94 deletions
@@ -173,18 +173,13 @@ data class ConeTypeVariableType(
override val typeArguments: Array<out ConeKotlinTypeProjection> get() = emptyArray() override val typeArguments: Array<out ConeKotlinTypeProjection> get() = emptyArray()
} }
class ConeDefinitelyNotNullType private constructor(val original: ConeKotlinType) : ConeSimpleKotlinType(), DefinitelyNotNullTypeMarker { data class ConeDefinitelyNotNullType(val original: ConeKotlinType) : ConeSimpleKotlinType(), DefinitelyNotNullTypeMarker {
override val typeArguments: Array<out ConeKotlinTypeProjection> override val typeArguments: Array<out ConeKotlinTypeProjection>
get() = original.typeArguments get() = original.typeArguments
override val nullability: ConeNullability override val nullability: ConeNullability
get() = ConeNullability.NOT_NULL get() = ConeNullability.NOT_NULL
companion object { companion object
fun create(original: ConeKotlinType): ConeDefinitelyNotNullType {
if (original is ConeFlexibleType) return create(original.lowerBound)
return ConeDefinitelyNotNullType(original)
}
}
} }
class ConeRawType(lowerBound: ConeKotlinType, upperBound: ConeKotlinType) : ConeFlexibleType(lowerBound, upperBound), RawTypeMarker class ConeRawType(lowerBound: ConeKotlinType, upperBound: ConeKotlinType) : ConeFlexibleType(lowerBound, upperBound), RawTypeMarker
@@ -138,7 +138,7 @@ private fun coneFlexibleOrSimpleType(
type is ConeTypeParameterType || type.isNullable type is ConeTypeParameterType || type.isNullable
} }
) { ) {
return ConeDefinitelyNotNullType.create(lowerBound) return ConeDefinitelyNotNullType.create(lowerBound) ?: lowerBound
} }
} }
return lowerBound return lowerBound
@@ -269,7 +269,7 @@ fun <T : ConeKotlinType> T.withArguments(arguments: Array<out ConeKotlinTypeProj
return when (this) { return when (this) {
is ConeClassErrorType -> this is ConeClassErrorType -> this
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, arguments, nullability.isNullable) as T is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, arguments, nullability.isNullable) as T
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType.create(original.withArguments(arguments)) as T is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType.create(original.withArguments(arguments))!! as T
else -> error("Not supported: $this: ${this.render()}") else -> error("Not supported: $this: ${this.render()}")
} }
} }
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.symbols.invoke
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
@@ -144,8 +143,8 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
} }
if (this is DefinitelyNotNullTypeMarker if (this is ConeDefinitelyNotNullType
&& this.original().containsInternal(predicate, visited) && this.original.containsInternal(predicate, visited)
) { ) {
return true return true
} }
@@ -198,11 +197,18 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
} }
override fun KotlinTypeMarker.makeDefinitelyNotNullOrNotNull(): KotlinTypeMarker { override fun KotlinTypeMarker.makeDefinitelyNotNullOrNotNull(): KotlinTypeMarker {
return this.withNullability(false) //TODO("not implemented") require(this is ConeKotlinType)
return makeDefinitelyNotNullOrNotNull()
} }
override fun SimpleTypeMarker.makeSimpleTypeDefinitelyNotNullOrNotNull(): SimpleTypeMarker { override fun SimpleTypeMarker.makeSimpleTypeDefinitelyNotNullOrNotNull(): SimpleTypeMarker {
return this.withNullability(false) //TODO("not implemented") require(this is ConeKotlinType)
return makeDefinitelyNotNullOrNotNull() as SimpleTypeMarker
}
private fun ConeKotlinType.makeDefinitelyNotNullOrNotNull(): ConeKotlinType {
// TODO: add intersection types, see fun SimpleType.makeSimpleTypeDefinitelyNotNullOrNotNull() in SpecialTypes.kt
return ConeDefinitelyNotNullType.create(this) ?: this.withNullability(false) as ConeKotlinType
} }
override fun createCapturedType( override fun createCapturedType(
@@ -273,7 +279,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
TypeSubstitutorMarker { TypeSubstitutorMarker {
override fun substituteType(type: ConeKotlinType): ConeKotlinType? { override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
val new = map[type.typeConstructor()] ?: return null val new = map[type.typeConstructor()] ?: return null
return makeNullableIfNeed(type.isMarkedNullable, (new as ConeKotlinType).approximateIntegerLiteralType()) return (new as ConeKotlinType).approximateIntegerLiteralType().updateNullabilityIfNeeded(type)
} }
} }
} }
@@ -298,7 +304,6 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
return type return type
} }
override fun createErrorTypeWithCustomConstructor(debugName: String, constructor: TypeConstructorMarker): KotlinTypeMarker { override fun createErrorTypeWithCustomConstructor(debugName: String, constructor: TypeConstructorMarker): KotlinTypeMarker {
return ConeKotlinErrorType("$debugName c: $constructor") return ConeKotlinErrorType("$debugName c: $constructor")
} }
@@ -28,9 +28,12 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() {
return wrapProjection(projection, newType) return wrapProjection(projection, newType)
} }
fun makeNullableIfNeed(isNullable: Boolean, type: ConeKotlinType?): ConeKotlinType? { fun ConeKotlinType?.updateNullabilityIfNeeded(originalType: ConeKotlinType): ConeKotlinType? {
if (!isNullable) return type return when {
return type?.withNullability(ConeNullability.NULLABLE) originalType is ConeDefinitelyNotNullType -> this?.withNullability(ConeNullability.NOT_NULL)
originalType.isMarkedNullable -> this?.withNullability(ConeNullability.NULLABLE)
else -> this
}
} }
override fun substituteOrNull(type: ConeKotlinType): ConeKotlinType? { override fun substituteOrNull(type: ConeKotlinType): ConeKotlinType? {
@@ -65,8 +68,9 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() {
return ConeIntersectionType(substitutedTypes) return ConeIntersectionType(substitutedTypes)
} }
private fun ConeDefinitelyNotNullType.substituteOriginal(): ConeDefinitelyNotNullType? { private fun ConeDefinitelyNotNullType.substituteOriginal(): ConeKotlinType? {
return ConeDefinitelyNotNullType.create(substituteOrNull(original)?.withNullability(ConeNullability.NOT_NULL) ?: original) val substituted = substituteOrNull(original)?.withNullability(ConeNullability.NOT_NULL) ?: return null
return ConeDefinitelyNotNullType.create(substituted) ?: substituted
} }
private fun ConeFlexibleType.substituteBounds(): ConeFlexibleType? { private fun ConeFlexibleType.substituteBounds(): ConeFlexibleType? {
@@ -128,6 +132,6 @@ data class ChainedSubstitutor(private val first: ConeSubstitutor, private val se
data class ConeSubstitutorByMap(val substitution: Map<FirTypeParameterSymbol, ConeKotlinType>) : AbstractConeSubstitutor() { data class ConeSubstitutorByMap(val substitution: Map<FirTypeParameterSymbol, ConeKotlinType>) : AbstractConeSubstitutor() {
override fun substituteType(type: ConeKotlinType): ConeKotlinType? { override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
if (type !is ConeTypeParameterType) return null if (type !is ConeTypeParameterType) return null
return makeNullableIfNeed(type.isMarkedNullable, substitution[type.lookupTag.symbol]) return substitution[type.lookupTag.symbol].updateNullabilityIfNeeded(type)
} }
} }
@@ -227,6 +227,7 @@ class FirClassSubstitutionScope(
baseFunction.status, baseFunction.status,
fakeOverrideSymbol fakeOverrideSymbol
).apply { ).apply {
annotations += baseFunction.annotations
resolvePhase = baseFunction.resolvePhase resolvePhase = baseFunction.resolvePhase
valueParameters += baseFunction.valueParameters.zip( valueParameters += baseFunction.valueParameters.zip(
newParameterTypes ?: List(baseFunction.valueParameters.size) { null } newParameterTypes ?: List(baseFunction.valueParameters.size) { null }
@@ -296,6 +297,7 @@ class FirClassSubstitutionScope(
baseProperty.status baseProperty.status
).apply { ).apply {
resolvePhase = baseProperty.resolvePhase resolvePhase = baseProperty.resolvePhase
annotations += baseProperty.annotations
} }
} }
return symbol return symbol
@@ -315,6 +317,7 @@ class FirClassSubstitutionScope(
name, symbol, isVar, baseField.status name, symbol, isVar, baseField.status
).apply { ).apply {
resolvePhase = baseField.resolvePhase resolvePhase = baseField.resolvePhase
annotations += baseField.annotations
} }
} }
return symbol return symbol
@@ -38,3 +38,19 @@ fun ConeInferenceContext.intersectTypesOrNull(types: List<ConeKotlinType>): Cone
else -> ConeTypeIntersector.intersectTypes(this, types) else -> ConeTypeIntersector.intersectTypes(this, types)
} }
} }
fun ConeDefinitelyNotNullType.Companion.create(original: ConeKotlinType): ConeDefinitelyNotNullType? {
return when {
original is ConeDefinitelyNotNullType -> original
makesSenseToBeDefinitelyNotNull(original) -> ConeDefinitelyNotNullType(original.lowerBoundIfFlexible())
else -> null
}
}
fun makesSenseToBeDefinitelyNotNull(type: ConeKotlinType): Boolean =
type.canHaveUndefinedNullability() // TODO: also check nullability
fun ConeKotlinType.canHaveUndefinedNullability(): Boolean =
this is ConeTypeVariableType ||
this is ConeTypeParameterType ||
this is ConeCapturedType
@@ -6,7 +6,7 @@ FILE: test.kt
} }
public final fun create(d: R|Diagnostic<DerivedElement>|): R|kotlin/Unit| { public final fun create(d: R|Diagnostic<DerivedElement>|): R|kotlin/Unit| {
lval element: R|DerivedElement!!| = R|<local>/d|.R|/Diagnostic.element| lval element: R|DerivedElement| = R|<local>/d|.R|/Diagnostic.element|
R|/Fix.Fix|(R|<local>/element|) R|/Fix.Fix|(R|<local>/element|)
} }
public final fun <DE : R|DerivedElement|> createGeneric(d: R|Diagnostic<DE>|): R|kotlin/Unit| { public final fun <DE : R|DerivedElement|> createGeneric(d: R|Diagnostic<DE>|): R|kotlin/Unit| {
@@ -16,7 +16,7 @@ FILE: test.kt
private final val DERIVED_FACTORY: R|DiagnosticFactory0<DerivedElement>| = R|/DiagnosticFactory0.DiagnosticFactory0|<R|DerivedElement|>() private final val DERIVED_FACTORY: R|DiagnosticFactory0<DerivedElement>| = R|/DiagnosticFactory0.DiagnosticFactory0|<R|DerivedElement|>()
private get(): R|DiagnosticFactory0<DerivedElement>| private get(): R|DiagnosticFactory0<DerivedElement>|
public final fun createViaFactory(d: R|EmptyDiagnostic|): R|kotlin/Unit| { public final fun createViaFactory(d: R|EmptyDiagnostic|): R|kotlin/Unit| {
lval casted: R|Diagnostic<DerivedElement>!!| = R|/DERIVED_FACTORY|.R|FakeOverride</DiagnosticFactory.cast: R|Diagnostic<DerivedElement>!!|>|(R|<local>/d|) lval casted: R|Diagnostic<DerivedElement>| = R|/DERIVED_FACTORY|.R|FakeOverride</DiagnosticFactory.cast: R|Diagnostic<DerivedElement>|>|(R|<local>/d|)
lval element: R|DerivedElement!!| = R|<local>/casted|.R|/Diagnostic.element| lval element: R|DerivedElement| = R|<local>/casted|.R|/Diagnostic.element|
R|/Fix.Fix|(R|<local>/element|) R|/Fix.Fix|(R|<local>/element|)
} }
@@ -0,0 +1,3 @@
fun test(elements: Array<out String?>) {
val filtered = elements.filterNotNull()
}
@@ -0,0 +1,4 @@
FILE: arrayFilterCapturedType.kt
public final fun test(elements: R|kotlin/Array<out kotlin/String?>|): R|kotlin/Unit| {
lval filtered: R|kotlin/collections/List<kotlin/String>| = R|<local>/elements|.R|kotlin/collections/filterNotNull|<R|kotlin/String|>()
}
@@ -1,3 +0,0 @@
fun test(elements: Array<out String?>) {
val filtered = elements.<!INAPPLICABLE_CANDIDATE("[kotlin/collections/filterNotNull]")!>filterNotNull<!>()
}
@@ -1,4 +0,0 @@
FILE: arrayFilterCapturedType.kt
public final fun test(elements: R|kotlin/Array<out kotlin/String?>|): R|kotlin/Unit| {
lval filtered: <ERROR TYPE REF: Inapplicable(WRONG_RECEIVER): [kotlin/collections/filterNotNull]> = R|<local>/elements|.<Inapplicable(WRONG_RECEIVER): [kotlin/collections/filterNotNull]>#()
}
@@ -1,3 +0,0 @@
fun test(map: Map<String?, List<String>>) {
val sortedMap = map.<!INAPPLICABLE_CANDIDATE!>toSortedMap<!>(nullsLast())
}
@@ -1,4 +0,0 @@
FILE: toSortedMapWithComparator.kt
public final fun test(map: R|kotlin/collections/Map<kotlin/String?, kotlin/collections/List<kotlin/String>>|): R|kotlin/Unit| {
lval sortedMap: <ERROR TYPE REF: Inapplicable(INAPPLICABLE): [kotlin/collections/toSortedMap]> = R|<local>/map|.<Inapplicable(INAPPLICABLE): [kotlin/collections/toSortedMap]>#(R|kotlin/comparisons/nullsLast|<R|kotlin/Any?|>())
}
@@ -0,0 +1,3 @@
fun test(map: Map<String?, List<String>>) {
val sortedMap = map.toSortedMap(nullsLast())
}
@@ -0,0 +1,4 @@
FILE: toSortedMapWithComparator.kt
public final fun test(map: R|kotlin/collections/Map<kotlin/String?, kotlin/collections/List<kotlin/String>>|): R|kotlin/Unit| {
lval sortedMap: R|java/util/SortedMap<kotlin/String?, kotlin/collections/List<kotlin/String>>| = R|<local>/map|.R|kotlin/collections/toSortedMap|<R|kotlin/String?|, R|kotlin/collections/List<kotlin/String>|>(R|kotlin/comparisons/nullsLast|<R|kotlin/String|>())
}
@@ -38,6 +38,11 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic
runTest("compiler/fir/resolve/testData/resolve/stdlib/anonymousInDelegate.kt"); runTest("compiler/fir/resolve/testData/resolve/stdlib/anonymousInDelegate.kt");
} }
@TestMetadata("arrayFilterCapturedType.kt")
public void testArrayFilterCapturedType() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/arrayFilterCapturedType.kt");
}
@TestMetadata("arrayFirstOrNull.kt") @TestMetadata("arrayFirstOrNull.kt")
public void testArrayFirstOrNull() throws Exception { public void testArrayFirstOrNull() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/arrayFirstOrNull.kt"); runTest("compiler/fir/resolve/testData/resolve/stdlib/arrayFirstOrNull.kt");
@@ -53,6 +58,11 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic
runTest("compiler/fir/resolve/testData/resolve/stdlib/backingField.kt"); runTest("compiler/fir/resolve/testData/resolve/stdlib/backingField.kt");
} }
@TestMetadata("classLiteralForParameter.kt")
public void testClassLiteralForParameter() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/classLiteralForParameter.kt");
}
@TestMetadata("companionLoad.kt") @TestMetadata("companionLoad.kt")
public void testCompanionLoad() throws Exception { public void testCompanionLoad() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/companionLoad.kt"); runTest("compiler/fir/resolve/testData/resolve/stdlib/companionLoad.kt");
@@ -198,6 +208,11 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic
runTest("compiler/fir/resolve/testData/resolve/stdlib/simpleLazy.kt"); runTest("compiler/fir/resolve/testData/resolve/stdlib/simpleLazy.kt");
} }
@TestMetadata("toSortedMapWithComparator.kt")
public void testToSortedMapWithComparator() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/toSortedMapWithComparator.kt");
}
@TestMetadata("topLevelResolve.kt") @TestMetadata("topLevelResolve.kt")
public void testTopLevelResolve() throws Exception { public void testTopLevelResolve() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/topLevelResolve.kt"); runTest("compiler/fir/resolve/testData/resolve/stdlib/topLevelResolve.kt");
@@ -592,16 +607,6 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/stdlib/problems"), Pattern.compile("^([^.]+)\\.kt$"), null, true); KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/stdlib/problems"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
} }
@TestMetadata("arrayFilterCapturedType.kt")
public void testArrayFilterCapturedType() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/problems/arrayFilterCapturedType.kt");
}
@TestMetadata("classLiteralForParameter.kt")
public void testClassLiteralForParameter() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/problems/classLiteralForParameter.kt");
}
@TestMetadata("cloneArray.kt") @TestMetadata("cloneArray.kt")
public void testCloneArray() throws Exception { public void testCloneArray() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/problems/cloneArray.kt"); runTest("compiler/fir/resolve/testData/resolve/stdlib/problems/cloneArray.kt");
@@ -617,11 +622,6 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic
runTest("compiler/fir/resolve/testData/resolve/stdlib/problems/inapplicableRemoveAll.kt"); runTest("compiler/fir/resolve/testData/resolve/stdlib/problems/inapplicableRemoveAll.kt");
} }
@TestMetadata("toSortedMapWithComparator.kt")
public void testToSortedMapWithComparator() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/problems/toSortedMapWithComparator.kt");
}
@TestMetadata("tryWithLambdaInside.kt") @TestMetadata("tryWithLambdaInside.kt")
public void testTryWithLambdaInside() throws Exception { public void testTryWithLambdaInside() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/problems/tryWithLambdaInside.kt"); runTest("compiler/fir/resolve/testData/resolve/stdlib/problems/tryWithLambdaInside.kt");
@@ -7,10 +7,10 @@ fun <E : CharSequence> foo1(x: E) {}
fun <E : CharSequence> E.foo2() {} fun <E : CharSequence> E.foo2() {}
fun <F : String?> bar(x: F) { fun <F : String?> bar(x: F) {
<!INAPPLICABLE_CANDIDATE!>A<!>(x) A(x)
<!INAPPLICABLE_CANDIDATE!>A<!><F>(x) <!INAPPLICABLE_CANDIDATE!>A<!><F>(x)
<!INAPPLICABLE_CANDIDATE!>foo1<!>(x) foo1(x)
<!INAPPLICABLE_CANDIDATE!>foo1<!><F>(x) <!INAPPLICABLE_CANDIDATE!>foo1<!><F>(x)
x.<!INAPPLICABLE_CANDIDATE!>foo2<!>() x.<!INAPPLICABLE_CANDIDATE!>foo2<!>()
@@ -45,7 +45,7 @@ fun <T : CharSequence?> foo(x: T) {
bar2(x) bar2(x)
<!INAPPLICABLE_CANDIDATE!>bar3<!>(x) <!INAPPLICABLE_CANDIDATE!>bar3<!>(x)
<!INAPPLICABLE_CANDIDATE!>bar1<!>(y) bar1(y)
bar2(y) bar2(y)
<!INAPPLICABLE_CANDIDATE!>bar3<!>(y) <!INAPPLICABLE_CANDIDATE!>bar3<!>(y)
} }
@@ -38,7 +38,7 @@ class A<F> {
x4.checkType { _<Z>() } x4.checkType { _<Z>() }
<!INAPPLICABLE_CANDIDATE!>foo1<!><W>(w) <!INAPPLICABLE_CANDIDATE!>foo1<!><W>(w)
<!INAPPLICABLE_CANDIDATE!>foo1<!>(w) foo1(w)
foo2<W>(w) foo2<W>(w)
val x6 = foo2(w) val x6 = foo2(w)
@@ -13,6 +13,6 @@ fun <T : String?> foo(x: T) {
bar1(x) bar1(x)
bar2(x) bar2(x)
<!INAPPLICABLE_CANDIDATE!>bar3<!>(x) bar3(x)
bar4(x) bar4(x)
} }
@@ -1,5 +1,5 @@
fun <S : Any> foo(x: Array<out S?>, y: Array<in S?>) { fun <S : Any> foo(x: Array<out S?>, y: Array<in S?>) {
val xo = <!INAPPLICABLE_CANDIDATE!>outA<!>(x) val xo = outA(x)
val yo = inA(y) val yo = inA(y)
var f: Array<S> = xo var f: Array<S> = xo
@@ -16,5 +16,5 @@ fun <T : Any> test() {
value = JClass.getNotNullT() value = JClass.getNotNullT()
} }
value.<!INAPPLICABLE_CANDIDATE!>hashCode<!>() // unsafe call error value.hashCode() // unsafe call error
} }
@@ -36,6 +36,6 @@ fun test() {
B1().bar(null) B1().bar(null)
B2().bar(null) B2().bar(null)
C1().<!AMBIGUITY!>bar<!>(null) C1().bar(null)
} }
@@ -27,7 +27,7 @@ FILE fqName:<root> fileName:/implicitCastToNonNull.kt
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: CALL 'public abstract fun <get-length> (): kotlin.Int declared in kotlin.CharSequence' type=kotlin.Int origin=null then: CALL 'public abstract fun <get-length> (): kotlin.Int declared in kotlin.CharSequence' type=kotlin.Int origin=null
$this: GET_VAR 'x: T of <root>.test2 declared in <root>.test2' type=kotlin.Any origin=null $this: GET_VAR 'x: T of <root>.test2 declared in <root>.test2' type=T of <root>.test2 origin=null
FUN name:test3 visibility:public modality:FINAL <T> (x:kotlin.Any) returnType:kotlin.Int [inline] FUN name:test3 visibility:public modality:FINAL <T> (x:kotlin.Any) returnType:kotlin.Int [inline]
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.CharSequence?] TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.CharSequence?]
VALUE_PARAMETER name:x index:0 type:kotlin.Any VALUE_PARAMETER name:x index:0 type:kotlin.Any
@@ -70,4 +70,4 @@ FILE fqName:<root> fileName:/implicitCastToNonNull.kt
arg1: CONST Null type=kotlin.Nothing? value=null arg1: CONST Null type=kotlin.Nothing? value=null
then: CALL 'public abstract fun invoke (p1: S of <root>.test5): kotlin.Unit [operator] declared in kotlin.Function1' type=kotlin.Unit origin=null then: CALL 'public abstract fun invoke (p1: S of <root>.test5): kotlin.Unit [operator] declared in kotlin.Function1' type=kotlin.Unit origin=null
$this: GET_VAR 'fn: kotlin.Function1<S of <root>.test5, kotlin.Unit> declared in <root>.test5' type=kotlin.Function1<S of <root>.test5, kotlin.Unit> origin=null $this: GET_VAR 'fn: kotlin.Function1<S of <root>.test5, kotlin.Unit> declared in <root>.test5' type=kotlin.Function1<S of <root>.test5, kotlin.Unit> origin=null
p1: GET_VAR 'x: T of <root>.test5 declared in <root>.test5' type=kotlin.Any origin=null p1: GET_VAR 'x: T of <root>.test5 declared in <root>.test5' type=T of <root>.test5 origin=null
+30 -30
View File
@@ -11,10 +11,10 @@ FILE fqName:<root> fileName:/kt30796.kt
VALUE_PARAMETER name:value2 index:1 type:T of <root>.test VALUE_PARAMETER name:value2 index:1 type:T of <root>.test
BLOCK_BODY BLOCK_BODY
VAR name:x1 type:kotlin.Any [val] VAR name:x1 type:kotlin.Any [val]
BLOCK type=kotlin.Any origin=ELVIS BLOCK type=T of <root>.test origin=ELVIS
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:T of <root>.test [val] VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:T of <root>.test [val]
GET_VAR 'value: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null GET_VAR 'value: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null
WHEN type=kotlin.Any origin=ELVIS WHEN type=T of <root>.test origin=ELVIS
BRANCH BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp_0: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null arg0: GET_VAR 'val tmp_0: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
@@ -22,20 +22,20 @@ FILE fqName:<root> fileName:/kt30796.kt
then: CONST Int type=kotlin.Int value=42 then: CONST Int type=kotlin.Int value=42
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'val tmp_0: T of <root>.test [val] declared in <root>.test' type=kotlin.Any origin=null then: GET_VAR 'val tmp_0: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
VAR name:x2 type:kotlin.Any [val] VAR name:x2 type:kotlin.Any [val]
BLOCK type=kotlin.Any origin=ELVIS BLOCK type=T of <root>.test origin=ELVIS
VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:T of <root>.test [val] VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:T of <root>.test [val]
GET_VAR 'value: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null GET_VAR 'value: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null
WHEN type=kotlin.Any origin=ELVIS WHEN type=T of <root>.test origin=ELVIS
BRANCH BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp_1: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null arg0: GET_VAR 'val tmp_1: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
arg1: CONST Null type=kotlin.Nothing? value=null arg1: CONST Null type=kotlin.Nothing? value=null
then: BLOCK type=kotlin.Any origin=ELVIS then: BLOCK type=T of <root>.test origin=ELVIS
VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:T of <root>.test [val] VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:T of <root>.test [val]
GET_VAR 'value2: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null GET_VAR 'value2: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null
WHEN type=kotlin.Any origin=ELVIS WHEN type=T of <root>.test origin=ELVIS
BRANCH BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp_2: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null arg0: GET_VAR 'val tmp_2: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
@@ -43,12 +43,12 @@ FILE fqName:<root> fileName:/kt30796.kt
then: CONST Int type=kotlin.Int value=42 then: CONST Int type=kotlin.Int value=42
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'val tmp_2: T of <root>.test [val] declared in <root>.test' type=kotlin.Any origin=null then: GET_VAR 'val tmp_2: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'val tmp_1: T of <root>.test [val] declared in <root>.test' type=kotlin.Any origin=null then: GET_VAR 'val tmp_1: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
VAR name:x3 type:kotlin.Any [val] VAR name:x3 type:kotlin.Any [val]
BLOCK type=kotlin.Any origin=ELVIS BLOCK type=T of <root>.test origin=ELVIS
VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:T of <root>.test [val] VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:T of <root>.test [val]
BLOCK type=T of <root>.test origin=ELVIS BLOCK type=T of <root>.test origin=ELVIS
VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:T of <root>.test [val] VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:T of <root>.test [val]
@@ -61,8 +61,8 @@ FILE fqName:<root> fileName:/kt30796.kt
then: GET_VAR 'value2: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null then: GET_VAR 'value2: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'val tmp_4: T of <root>.test [val] declared in <root>.test' type=kotlin.Any origin=null then: GET_VAR 'val tmp_4: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
WHEN type=kotlin.Any origin=ELVIS WHEN type=T of <root>.test origin=ELVIS
BRANCH BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp_3: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null arg0: GET_VAR 'val tmp_3: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
@@ -70,9 +70,9 @@ FILE fqName:<root> fileName:/kt30796.kt
then: CONST Int type=kotlin.Int value=42 then: CONST Int type=kotlin.Int value=42
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'val tmp_3: T of <root>.test [val] declared in <root>.test' type=kotlin.Any origin=null then: GET_VAR 'val tmp_3: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
VAR name:x4 type:kotlin.Any [val] VAR name:x4 type:kotlin.Any [val]
BLOCK type=kotlin.Any origin=ELVIS BLOCK type=T of <root>.test origin=ELVIS
VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:T of <root>.test [val] VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:T of <root>.test [val]
BLOCK type=T of <root>.test origin=ELVIS BLOCK type=T of <root>.test origin=ELVIS
VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:T of <root>.test [val] VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:T of <root>.test [val]
@@ -85,8 +85,8 @@ FILE fqName:<root> fileName:/kt30796.kt
then: GET_VAR 'value2: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null then: GET_VAR 'value2: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'val tmp_6: T of <root>.test [val] declared in <root>.test' type=kotlin.Any origin=null then: GET_VAR 'val tmp_6: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
WHEN type=kotlin.Any origin=ELVIS WHEN type=T of <root>.test origin=ELVIS
BRANCH BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp_5: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null arg0: GET_VAR 'val tmp_5: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
@@ -94,7 +94,7 @@ FILE fqName:<root> fileName:/kt30796.kt
then: CONST Int type=kotlin.Int value=42 then: CONST Int type=kotlin.Int value=42
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'val tmp_5: T of <root>.test [val] declared in <root>.test' type=kotlin.Any origin=null then: GET_VAR 'val tmp_5: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
VAR name:x5 type:kotlin.Any [val] VAR name:x5 type:kotlin.Any [val]
BLOCK type=kotlin.Int origin=ELVIS BLOCK type=kotlin.Int origin=ELVIS
VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:kotlin.Nothing [val] VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:kotlin.Nothing [val]
@@ -110,32 +110,32 @@ FILE fqName:<root> fileName:/kt30796.kt
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'val tmp_7: kotlin.Nothing [val] declared in <root>.test' type=kotlin.Nothing origin=null then: GET_VAR 'val tmp_7: kotlin.Nothing [val] declared in <root>.test' type=kotlin.Nothing origin=null
VAR name:x6 type:kotlin.Any [val] VAR name:x6 type:kotlin.Any [val]
BLOCK type=kotlin.Any origin=ELVIS BLOCK type=T of <root>.test origin=ELVIS
VAR IR_TEMPORARY_VARIABLE name:tmp_8 type:kotlin.Any [val] VAR IR_TEMPORARY_VARIABLE name:tmp_8 type:T of <root>.test [val]
BLOCK type=kotlin.Any origin=ELVIS BLOCK type=T of <root>.test origin=ELVIS
VAR IR_TEMPORARY_VARIABLE name:tmp_9 type:T of <root>.test [val] VAR IR_TEMPORARY_VARIABLE name:tmp_9 type:T of <root>.test [val]
GET_VAR 'value: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null GET_VAR 'value: T of <root>.test declared in <root>.test' type=T of <root>.test origin=null
WHEN type=kotlin.Any origin=ELVIS WHEN type=T of <root>.test origin=ELVIS
BRANCH BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp_9: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null arg0: GET_VAR 'val tmp_9: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
arg1: CONST Null type=kotlin.Nothing? value=null arg1: CONST Null type=kotlin.Nothing? value=null
then: CALL 'public final fun magic <T> (): T of <root>.magic declared in <root>' type=kotlin.Any origin=null then: CALL 'public final fun magic <T> (): T of <root>.magic declared in <root>' type=T of <root>.test origin=null
<T>: kotlin.Any <T>: T of <root>.test
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'val tmp_9: T of <root>.test [val] declared in <root>.test' type=kotlin.Any origin=null then: GET_VAR 'val tmp_9: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
WHEN type=kotlin.Any origin=ELVIS WHEN type=T of <root>.test origin=ELVIS
BRANCH BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp_8: kotlin.Any [val] declared in <root>.test' type=kotlin.Any origin=null arg0: GET_VAR 'val tmp_8: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
arg1: CONST Null type=kotlin.Nothing? value=null arg1: CONST Null type=kotlin.Nothing? value=null
then: CONST Int type=kotlin.Int value=42 then: CONST Int type=kotlin.Int value=42
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'val tmp_8: kotlin.Any [val] declared in <root>.test' type=kotlin.Any origin=null then: GET_VAR 'val tmp_8: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
VAR name:x7 type:kotlin.Any [val] VAR name:x7 type:kotlin.Any [val]
BLOCK type=kotlin.Any origin=ELVIS BLOCK type=T of <root>.test origin=ELVIS
VAR IR_TEMPORARY_VARIABLE name:tmp_10 type:T of <root>.test [val] VAR IR_TEMPORARY_VARIABLE name:tmp_10 type:T of <root>.test [val]
BLOCK type=T of <root>.test origin=ELVIS BLOCK type=T of <root>.test origin=ELVIS
VAR IR_TEMPORARY_VARIABLE name:tmp_11 type:kotlin.Nothing [val] VAR IR_TEMPORARY_VARIABLE name:tmp_11 type:kotlin.Nothing [val]
@@ -150,7 +150,7 @@ FILE fqName:<root> fileName:/kt30796.kt
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'val tmp_11: kotlin.Nothing [val] declared in <root>.test' type=kotlin.Nothing origin=null then: GET_VAR 'val tmp_11: kotlin.Nothing [val] declared in <root>.test' type=kotlin.Nothing origin=null
WHEN type=kotlin.Any origin=ELVIS WHEN type=T of <root>.test origin=ELVIS
BRANCH BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp_10: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null arg0: GET_VAR 'val tmp_10: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null
@@ -158,4 +158,4 @@ FILE fqName:<root> fileName:/kt30796.kt
then: CONST Int type=kotlin.Int value=42 then: CONST Int type=kotlin.Int value=42
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: GET_VAR 'val tmp_10: T of <root>.test [val] declared in <root>.test' type=kotlin.Any origin=null then: GET_VAR 'val tmp_10: T of <root>.test [val] declared in <root>.test' type=T of <root>.test origin=null