[FIR] Use Function<R> as super type for all FunctionNtypes

This commit is contained in:
Dmitriy Novozhilov
2020-01-24 11:35:37 +03:00
parent 099d737e86
commit 7d8363d6aa
37 changed files with 57 additions and 47 deletions
@@ -40,6 +40,8 @@ object StandardClassIds {
val Comparable = "Comparable".baseId() val Comparable = "Comparable".baseId()
val Number = "Number".baseId() val Number = "Number".baseId()
val Function = "Function".baseId()
fun byName(name: String) = name.baseId() fun byName(name: String) = name.baseId()
fun reflectByName(name: String) = name.reflectId() fun reflectByName(name: String) = name.reflectId()
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider
import org.jetbrains.kotlin.fir.scopes.impl.nestedClassifierScope import org.jetbrains.kotlin.fir.scopes.impl.nestedClassifierScope
import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
@@ -250,18 +251,25 @@ class FirBuiltinSymbolProvider(val session: FirSession, val kotlinScopeProvider:
} }
val superTypes = when (kind) { val superTypes = when (kind) {
FunctionClassDescriptor.Kind.Function ->
listOf(
FirResolvedTypeRefImpl(
source = null,
ConeClassLikeLookupTagImpl(StandardClassIds.Function)
.constructClassType(arrayOf(typeArguments.last().type), isNullable = false)
)
)
FunctionClassDescriptor.Kind.Function,
FunctionClassDescriptor.Kind.SuspendFunction -> FunctionClassDescriptor.Kind.SuspendFunction ->
listOf(session.builtinTypes.anyType) listOf(session.builtinTypes.anyType)
FunctionClassDescriptor.Kind.KFunction -> FunctionClassDescriptor.Kind.KFunction ->
listOf(createSuperType(FunctionClassDescriptor.Kind.Function)) listOf(createSuperType(FunctionClassDescriptor.Kind.Function))
FunctionClassDescriptor.Kind.KSuspendFunction -> FunctionClassDescriptor.Kind.KSuspendFunction ->
listOf(createSuperType(FunctionClassDescriptor.Kind.SuspendFunction)) listOf(createSuperType(FunctionClassDescriptor.Kind.SuspendFunction))
} }
replaceSuperTypeRefs(superTypes) replaceSuperTypeRefs(superTypes)
} }
} }
} }
@@ -1,5 +1,5 @@
fun takeAnyFun(function: Function<*>) {} fun takeAnyFun(function: Function<*>) {}
fun test(block: () -> Unit) { fun test(block: () -> Unit) {
<!INAPPLICABLE_CANDIDATE!>takeAnyFun<!>(block) takeAnyFun(block)
} }
@@ -2,5 +2,5 @@ FILE: functionAndFunctionN.kt
public final fun takeAnyFun(function: R|kotlin/Function<*>|): R|kotlin/Unit| { public final fun takeAnyFun(function: R|kotlin/Function<*>|): R|kotlin/Unit| {
} }
public final fun test(block: R|() -> kotlin/Unit|): R|kotlin/Unit| { public final fun test(block: R|() -> kotlin/Unit|): R|kotlin/Unit| {
<Inapplicable(INAPPLICABLE): [/takeAnyFun]>#(R|<local>/block|) R|/takeAnyFun|(R|<local>/block|)
} }
@@ -83,6 +83,11 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic
runTest("compiler/fir/resolve/testData/resolve/stdlib/factoryFunctionOverloads.kt"); runTest("compiler/fir/resolve/testData/resolve/stdlib/factoryFunctionOverloads.kt");
} }
@TestMetadata("functionAndFunctionN.kt")
public void testFunctionAndFunctionN() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/functionAndFunctionN.kt");
}
@TestMetadata("functionX.kt") @TestMetadata("functionX.kt")
public void testFunctionX() throws Exception { public void testFunctionX() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/functionX.kt"); runTest("compiler/fir/resolve/testData/resolve/stdlib/functionX.kt");
@@ -607,11 +612,6 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic
runTest("compiler/fir/resolve/testData/resolve/stdlib/problems/delegateTypeMismatch.kt"); runTest("compiler/fir/resolve/testData/resolve/stdlib/problems/delegateTypeMismatch.kt");
} }
@TestMetadata("functionAndFunctionN.kt")
public void testFunctionAndFunctionN() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/problems/functionAndFunctionN.kt");
}
@TestMetadata("inapplicableRemoveAll.kt") @TestMetadata("inapplicableRemoveAll.kt")
public void testInapplicableRemoveAll() throws Exception { public void testInapplicableRemoveAll() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/problems/inapplicableRemoveAll.kt"); runTest("compiler/fir/resolve/testData/resolve/stdlib/problems/inapplicableRemoveAll.kt");
@@ -7,7 +7,7 @@ inline fun <R> callIt(fn: () -> R): R = TODO()
inline fun <R> callItContracted(fn: () -> R): R { inline fun <R> callItContracted(fn: () -> R): R {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(fn, InvocationKind.EXACTLY_ONCE) callsInPlace(fn, InvocationKind.EXACTLY_ONCE)
} }
TODO() TODO()
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.*
inline fun <T> myRun(block: () -> T): T { inline fun <T> myRun(block: () -> T): T {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block() return block()
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.*
inline fun <T> myRun(block: () -> T): T { inline fun <T> myRun(block: () -> T): T {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block() return block()
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.*
fun <T> myRun(block: () -> T): T { fun <T> myRun(block: () -> T): T {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block() return block()
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.*
inline fun myRun(block: () -> Unit): Unit { inline fun myRun(block: () -> Unit): Unit {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
block() block()
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.*
inline fun myRun(block: () -> Unit): Unit { inline fun myRun(block: () -> Unit): Unit {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block() return block()
} }
@@ -6,14 +6,14 @@ import kotlin.contracts.*
inline fun <T> myRun(block: () -> T): T { inline fun <T> myRun(block: () -> T): T {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block() return block()
} }
inline fun <T, R> T.myLet(block: (T) -> R): R { inline fun <T, R> T.myLet(block: (T) -> R): R {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block(this) return block(this)
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.*
inline fun <T> myRun(block: () -> T): T { inline fun <T> myRun(block: () -> T): T {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block() return block()
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.*
inline fun <T> myRun(block: () -> T): T { inline fun <T> myRun(block: () -> T): T {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block() return block()
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.*
inline fun <T, R> T.myLet(block: (T) -> R): R { inline fun <T, R> T.myLet(block: (T) -> R): R {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block(this) return block(this)
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.*
inline fun myRun(block: () -> Unit): Unit { inline fun myRun(block: () -> Unit): Unit {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block() return block()
} }
@@ -5,7 +5,7 @@ import kotlin.contracts.*
inline fun <T> Any?.myRun(block: () -> T): T { inline fun <T> Any?.myRun(block: () -> T): T {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block() return block()
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.*
inline fun <T> myRun(block: () -> T): T { inline fun <T> myRun(block: () -> T): T {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block() return block()
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.*
inline fun myRun(block: () -> Unit) { inline fun myRun(block: () -> Unit) {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
block() block()
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.*
fun <T> myRun(block: () -> T): T { fun <T> myRun(block: () -> T): T {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block() return block()
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.*
inline fun <T> myRun(block: () -> T): T { inline fun <T> myRun(block: () -> T): T {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block() return block()
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.*
fun <T> myRun(block: () -> T): T { fun <T> myRun(block: () -> T): T {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block() return block()
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.*
inline fun <T> myRun(block: () -> T): T { inline fun <T> myRun(block: () -> T): T {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block() return block()
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.*
fun <T> runTwice(block: () -> T): T { fun <T> runTwice(block: () -> T): T {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.AT_LEAST_ONCE) callsInPlace(block, InvocationKind.AT_LEAST_ONCE)
} }
block() block()
return block(); return block();
@@ -14,7 +14,7 @@ fun <T> runTwice(block: () -> T): T {
fun <T> runOnce(block: () -> T): T { fun <T> runOnce(block: () -> T): T {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block(); return block();
}; };
@@ -6,7 +6,7 @@ import kotlin.contracts.*
fun <T> runTwice(block: () -> T): T { fun <T> runTwice(block: () -> T): T {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.AT_LEAST_ONCE) callsInPlace(block, InvocationKind.AT_LEAST_ONCE)
} }
block() block()
return block(); return block();
@@ -6,7 +6,7 @@ import kotlin.contracts.*
fun <T> runTwice(block: () -> T): T { fun <T> runTwice(block: () -> T): T {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.AT_LEAST_ONCE) callsInPlace(block, InvocationKind.AT_LEAST_ONCE)
} }
block() block()
return block(); return block();
@@ -6,7 +6,7 @@ import kotlin.contracts.*
fun <T> myRun(block: () -> T): T { fun <T> myRun(block: () -> T): T {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block() return block()
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.*
fun <T> myRun(block: () -> T): T { fun <T> myRun(block: () -> T): T {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block() return block()
} }
@@ -6,14 +6,14 @@ import kotlin.contracts.*
fun <T> myRun(block: () -> T): T { fun <T> myRun(block: () -> T): T {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block() return block()
} }
fun myRepeat(n: Int, action: () -> Unit) { fun myRepeat(n: Int, action: () -> Unit) {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(action) callsInPlace(action)
} }
for (i in 1..n) action() for (i in 1..n) action()
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.*
fun <T> myRun(block: () -> T): T { fun <T> myRun(block: () -> T): T {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block() return block()
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.*
fun <T> myRun(block: () -> T): T { fun <T> myRun(block: () -> T): T {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block() return block()
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.*
fun <T, R> T.myLet(block: (T) -> R): R { fun <T, R> T.myLet(block: (T) -> R): R {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
return block(this) return block(this)
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.*
fun <T> inPlace(block: () -> T): T { fun <T> inPlace(block: () -> T): T {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block) callsInPlace(block)
} }
return block() return block()
} }
@@ -15,23 +15,23 @@ fun foo(y: Boolean) {
inline fun case1(block: () -> Unit) { inline fun case1(block: () -> Unit) {
val contracts = listOf( val contracts = listOf(
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}, contract { }, contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
) )
block() block()
} }
inline fun case_2(block: () -> Unit) = contract { inline fun case_2(block: () -> Unit) = contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
fun case_3(block: () -> Unit) { fun case_3(block: () -> Unit) {
class Class { class Class {
fun innerFun(block2: () -> Unit) { fun innerFun(block2: () -> Unit) {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block2, InvocationKind.EXACTLY_ONCE) callsInPlace(block2, InvocationKind.EXACTLY_ONCE)
} }
block2() block2()
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.InvocationKind
inline fun foo(block: () -> Unit) { inline fun foo(block: () -> Unit) {
kotlin.contracts.contract { kotlin.contracts.contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
block() block()
} }
@@ -7,7 +7,7 @@ import kotlin.contracts.*
class Foo { class Foo {
fun myRun(block: () -> Unit) { fun myRun(block: () -> Unit) {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
block() block()
} }
@@ -6,7 +6,7 @@ import kotlin.contracts.*
fun callsAndInverts(b: Boolean, block: () -> Unit): Boolean { fun callsAndInverts(b: Boolean, block: () -> Unit): Boolean {
contract { contract {
<!INAPPLICABLE_CANDIDATE!>callsInPlace<!>(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
returns(true) implies (!b) returns(true) implies (!b)
returns(false) implies b returns(false) implies b
} }