From a5bfa3ae63f24fb75e434796829caa9d23b3f4cc Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Tue, 7 Jul 2020 11:46:01 +0300 Subject: [PATCH] [FIR-TEST] Update broken testdata --- .../postponedArgumentsAnalysis/basic.fir.kt | 340 ++++++++++-------- 1 file changed, 190 insertions(+), 150 deletions(-) diff --git a/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/basic.fir.kt b/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/basic.fir.kt index 0c02db8753d..8c30683f2a4 100644 --- a/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/basic.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/basic.fir.kt @@ -1,163 +1,30 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER -UNCHECKED_CAST + import kotlin.reflect.KFunction1 -// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER +fun withOverload(i: Int) {} +fun withOverload(s: String) {} + +fun takeInt(i: Int) {} +fun takeNumber(i: Number) {} -fun foo(i: Int) {} -fun foo(s: String) {} -fun foo2(i: Int) {} -fun foo3(i: Number) {} fun id(x: K): K = x fun id1(x: K): K = x fun id2(x: L): L = x -fun baz1(x: T, y: T): T = TODO() -fun baz2(x: T, y: Inv): T = TODO() + +fun selectWithInv(x: T, y: Inv): T = TODO() fun select(vararg x: T) = x[0] +fun takeLambdas(vararg x: (T) -> Unit) = x[0] +fun takeLambdasWithDirectlyDependentTypeParameters(x: (T) -> Unit, y: (R) -> Unit, z: (L) -> Unit) = x +fun takeLambdasWithInverselyDependentTypeParameters(x: (T) -> Unit, y: (R) -> Unit, z: (L) -> Unit) = x + fun takeInterdependentLambdas(x: (T) -> R, y: (R) -> T) {} fun takeDependentLambdas(x: (T) -> Int, y: (Int) -> T) {} class Inv(val x: T) -fun test1() { - val x1: (Int) -> Unit = id(id(::foo)) - val x2: (Int) -> Unit = baz1(id(::foo), ::foo) - val x3: (Int) -> Unit = baz1(id(::foo), id(id(::foo))) - val x4: (String) -> Unit = baz1(id(::foo), id(id(::foo))) - - id<(Int) -> Unit>(id(id(::foo))) - id(id<(Int) -> Unit>(::foo)) - baz1<(Int) -> Unit>(id(::foo), id(id(::foo))) - baz1(id(::foo), id(id<(Int) -> Unit>(::foo))) - baz1(id(::foo), id<(Int) -> Unit>(id(::foo))) - - baz1(id { it.inv() }, id<(Int) -> Unit> { }) - baz1(id1 { x -> x.inv() }, id2 { x: Int -> }) - baz1(id1 { it.inv() }, id2 { x: Int -> }) - - baz2(id1 { it.inv() }, id2(Inv { x: Int -> })) - - select(id1 { it.inv() }, id1 { x: Number -> TODO() }, id1(id2 { x: Int -> x })) - - select(id1 { it.inv() }, id1 { x: Number -> TODO() }, id1(id2(::foo2))) - select(id1 { x: Inv -> TODO() }, id1 { it.x.inv() }, id1 { x: Inv -> TODO() }) - - select(id1 { it }, id1 { x: Inv -> TODO() }, id1 { x: Inv -> TODO() }) - - ")!>select(id1(::foo), id(::foo3), id1(id2(::foo2))) - - select({ it }, { x: Int -> TODO() }) - - // Interdependent postponed arguments are unsupported - takeInterdependentLambdas({}, {}) - takeInterdependentLambdas({ it }, { 10 }) - takeInterdependentLambdas({ 10 }, { it }) - takeInterdependentLambdas({ 10 }, { x -> x }) - takeInterdependentLambdas({ x -> 10 }, { it }) - takeInterdependentLambdas({ it }, { x -> 10 }) - - takeDependentLambdas({ it }, { it }) - takeDependentLambdas({ it.length }, { "it" }) - takeDependentLambdas({ it; 10 }, { }) - - select({ it }, fun(x: Int) = 1) - - val x5: (Int) -> Unit = select({ it }, { x: Number -> Unit }) - val x6 = select(id { it }, id(id<(Int) -> Unit> { x: Number -> Unit })) - - select(id(id2 { it.inv() }), id(id { x: Int -> x })) - - val x7: (Int) -> Unit = selectNumber(id {}, id {}, id {}) - val x8: (Int) -> Unit = selectNumber(id { x -> x }, id { x -> }, id { x -> }) - val x9: (Int) -> Unit = selectNumber(id { }, id { x -> }, id { it }) - - val x10: (Int) -> Unit = selectFloat(id { }, id { x -> }, id { it }) - - val x11: (B) -> Unit = selectC(id { }, id { x -> x }, id { it }) - - /* - * Upper constraint is less specific than lower (it's error): - * K <: (A) -> Unit -> TypeVariable(_RP1) >: A - * K >: (C) -> TypeVariable(_R) -> TypeVariable(_RP1) <: C - */ - val x12 = selectC(id { it }, id { x: B -> }) - val x13 = selectA(id { it }, id { x: C -> }) - - // one upper constraint and one lower - val x14 = selectC(id { it }, id { x: A -> }, { x -> x }) - val x15 = selectC(id { it }, { x: A -> }, id { x -> x }) - - /* - * Two upper constraints and one lower - * K <: (C) -> Unit -> TypeVariable(_RP1) >: C - * K <: (B) -> Unit -> TypeVariable(_RP1) >: B - * K >: (A) -> TypeVariable(_R) -> TypeVariable(_RP1) <: A - * K == intersect(CST(C, B), A) == A - */ - val x16: (C) -> Unit = selectB(id { it }, { x -> }, id { x: A -> x }) - - /* - * two upper constraints and one equality (it's error) - * K <: (C) -> Unit -> TypeVariable(_RP1) >: C - * K == (B) -> Unit -> TypeVariable(_RP1) == B - */ - val x17: (C) -> Unit = selectB(id { it }, id { it }, id<(B) -> Unit> { x -> x }) - val x18: (C) -> Unit = select(id { it }, { it }, id<(B) -> Unit> { x -> x }) - - val x19: String.() -> Unit = select(")!>id {}, ")!>id(fun(x: String) {})) - val x20: String.() -> Unit = select(")!>{}, (fun(x: String) {})) - val x21: String.() -> Unit = select(")!>id(fun(x: String) {}), ")!>id(fun(x: String) {})) - val x22 = select(id Unit>(fun(x: String) {}), ")!>id(fun(x: String) {})) - val x23 = select(")!>id(fun String.(x: String) {}), ")!>id(fun(x: String, y: String) {})) - val x24 = select(id(fun String.(x: String) {}), id(fun(x: String, y: String) { }), { x: String -> this }) - val x25 = select(id(fun String.(x: String) {}), id(fun(x: String, y: String) { }), { x: String, y: String -> x }) - - // It isn't related with posponed arguments, see KT-38439 - val x26: Int.(String) -> Int = fun (x: String) = 10 - val x27: Int.(String) -> Int = id(fun (x: String) = 10) - - val x28 = select(id { x, y -> x.inv() + y.toByte() }, { x: Int, y -> y.toByte() }, { x, y: Number -> x.inv() }) - val x29 = select(id { x, y -> x.inv() + y.toByte() }, id { x: Int, y -> y.toByte() }, id { x, y: Number -> x.inv() }) - val x30 = select({ x, y -> x.inv() + y.toByte() }, id { x: Int, y -> y.toByte() }, id { x, y: Number -> x.inv() }) - - val x31 = select( - id { x, y -> x.inv() + y.toByte() }, - id<(Int, Number) -> Int> { x, y -> x.inv() }, - {} as (Number, Number) -> Int - ) - - val x32 = selectPosponedArgument({ it }, { x: Int -> }, { x: Nothing -> x }) - val x33 = selectPosponedArgument({ it }, { } as (Int) -> Unit, { x: Nothing -> x }) - val x34 = selectPosponedArgument({ it }, { } as (Nothing) -> Unit, { x: Int -> x }) - val x35 = selectPosponedArgument({ it }, { } as (Int) -> Unit, { } as (Nothing) -> Unit) - - val x36 = selectPosponedArgument3({ it }, { it }, { x: Int -> x }) - val x37 = selectPosponedArgument3({ it }, { x: Number -> x }, { x: Int -> x }) - val x38 = selectPosponedArgument3Revert({ it }, { it }, { x: Int -> x }) - val x39 = selectPosponedArgument3Revert({ it }, { x: Number -> x }, { x: Int -> x }) - - val x40 = select(id Unit> {}, { x: Int, y: String -> x }) - - val x41 = select(A2(), { a, b, c -> a; b; c }) - val x42 = select(A3(), { it }, { a -> a }) - val x43 = select(A3(), ")!>A3::foo1) - val x44 = select(A3(), ")!>A3::foo1, { a -> a }, { it -> it }) - - val x45 = select(A4(), { x: Number -> "" }) - val x46 = select(A5(), { x: Number, y: Int -> "" }) - - val x47 = select(A2(), id { a, b, c -> a; b; c }) - val x48 = select(id(A3()), { it }, { a -> a }) - val x49 = select(A3(), id(")!>A3::foo1)) - val x50 = select(A3(), ")!>A3::foo1, { a -> a }, { it -> it }) - - val x51 = select(A4(), id { x: Number -> x }) - val x52 = select(id(A5()), id { x: Number, y: Int -> x;y }) - val x53 = select(id(A5()), id { x, y -> x;y }) - val x54 = select(id(")!>A5()), id { x: Number, y: Int -> x;y }) - val x55: Function2 = select(id(A5()), id { x, y -> x;y; 1f }) -} - fun Unit> selectNumber(arg1: T, arg2: T, arg3: T) = arg1 fun Unit> selectFloat(arg1: T, arg2: T, arg3: T) = arg2 @@ -166,10 +33,6 @@ fun Unit> selectA(arg1: T, arg2: T, arg3: T) = arg2 fun Unit> selectB(arg1: T, arg2: T, arg3: T) = arg2 fun Unit> selectC(arg1: T, arg2: T, arg3: T) = arg2 -fun selectPosponedArgument(vararg x: (T) -> Unit) = x[0] -fun selectPosponedArgument3(x: (T) -> Unit, y: (R) -> Unit, z: (L) -> Unit) = x -fun selectPosponedArgument3Revert(x: (T) -> Unit, y: (R) -> Unit, z: (L) -> Unit) = x - interface A class B: A class C: A @@ -184,6 +47,11 @@ class A3: KFunction1 { fun foo1(x: Int) {} fun foo1(x: Any?) {} + + companion object { + fun foo2(x: Int) {} + fun foo2(x: Any?) {} + } } class A4: Function1 { @@ -193,3 +61,175 @@ class A4: Function1 { class A5: Function2 { override fun invoke(p1: K, p2: Q): Float = 5f } + +fun main() { + // Inferring lambda parameter types by other lambda explicit parameters; expected type is type variable + select(id1 { x -> x.inv() }, id2 { x: Int -> }) + select(id1 { it.inv() }, id2 { x: Int -> }) + selectWithInv(id1 { it.inv() }, id2(Inv { x: Int -> })) + select(id1 { it.inv() }, id1 { x: Number -> TODO() }, id1(id2 { x: Int -> x })) + select(id1 { it.inv() }, id1 { x: Number -> TODO() }, id1(id2(::takeInt))) + select(id1 { x: Inv -> TODO() }, id1 { it.x.inv() }, id1 { x: Inv -> TODO() }) + select(id1 { it }, id1 { x: Inv -> TODO() }, id1 { x: Inv -> TODO() }) + select(id(id2 { it.inv() }), id(id { x: Int -> x })) + + // Disambiguating callable references by other callable references without overloads + ")!>select(id(::withOverload), id(::takeInt), id(id(::takeNumber))) + + // Interdependent lambdas by input-output types aren't supported + takeInterdependentLambdas({}, {}) + takeInterdependentLambdas({ it }, { 10 }) + takeInterdependentLambdas({ 10 }, { it }) + takeInterdependentLambdas({ 10 }, { x -> x }) + takeInterdependentLambdas({ x -> 10 }, { it }) + takeInterdependentLambdas({ it }, { x -> 10 }) + + // Dependent lambdas by input-output types + takeDependentLambdas({ it }, { it }) + takeDependentLambdas({ it.length }, { "it" }) + takeDependentLambdas({ it; 10 }, { }) + + // Inferring lambda parameter types by anonymous function parameters + select({ it }, fun(x: Int) = 1) + + // Inferring lambda parameter types by other lambda explicit parameters (lower constraints) and expected type (upper constraints) + val x5: (Int) -> Unit = select({ it }, { x: Number -> Unit }) + + // Inferring lambda parameter types by other lambda explicit parameters (lower constraints) and specified type arguments (equality constraints) + select(id { it }, id(id<(Int) -> Unit> { x: Number -> Unit })) + + // Inferring lambda parameter types by specified type arguments (equality constraints) of other lambdas + select(id { it.inv() }, id<(Int) -> Unit> { }) + select( + id { x, y -> x.inv() + y.toByte() }, + id<(Int, Number) -> Int> { x, y -> x.inv() }, + {} as (Number, Number) -> Int + ) + + // Inferring lambda parameter types by a few expected types (a few upper constraints) + val x7: (Int) -> Unit = ")!>selectNumber(id {}, id {}, id {}) + val x8: (Int) -> Unit = selectNumber(id { x -> x }, id { x -> }, id { x -> }) + val x9: (Int) -> Unit = selectNumber(id { }, id { x -> }, id { it }) + val x10: (Int) -> Unit = selectFloat(id { }, id { x -> }, id { it }) + val x11: (B) -> Unit = selectC(id { }, id { x -> x }, id { it }) + + // Inferring lambda parameter types by expected types (upper constraints) and other lambda explicit parameters (lower constraints) + /* + * Upper constraint is less specific than lower (it's error): + * K <: (A) -> Unit -> TypeVariable(_RP1) >: A + * K >: (C) -> TypeVariable(_R) -> TypeVariable(_RP1) <: C + */ + val x12 = selectC(id { it }, id { x: B -> }) + val x13 = selectA(id { it }, id { x: C -> }) + val x14 = selectC(id { it }, id { x: A -> }, { x -> x }) + val x15 = selectC(id { it }, { x: A -> }, id { x -> x }) + /* + * Two upper constraints and one lower + * K <: (C) -> Unit -> TypeVariable(_RP1) >: C + * K <: (B) -> Unit -> TypeVariable(_RP1) >: B + * K >: (A) -> TypeVariable(_R) -> TypeVariable(_RP1) <: A + * K == intersect(CST(C, B), A) == A + */ + val x16: (C) -> Unit = selectB(id { it }, { x -> }, id { x: A -> x }) + + // Inferring lambda parameter types by expected types (upper constraints) and specified type arguments (equality constraints) of other lambdas + /* + * two upper constraints and one equality (it's error) + * K <: (C) -> Unit -> TypeVariable(_RP1) >: C + * K == (B) -> Unit -> TypeVariable(_RP1) == B + */ + val x17: (C) -> Unit = selectB(id { it }, id { it }, id<(B) -> Unit> { x -> x }) + val x18: (C) -> Unit = select(id { it }, { it }, id<(B) -> Unit> { x -> x }) + + // Resolution of extension/non-extension functions combination + val x19: String.() -> Unit = select(")!>id { this }, ")!>id(fun(x: String) {})) + val x20: String.() -> Unit = select(")!>{ this }, (fun(x: String) {})) + val x21: String.() -> Unit = select(")!>id(fun(x: String) {}), ")!>id(fun(x: String) {})) + select(id Unit>(fun(x: String) {}), ")!>id(fun(x: String) {})) + select(")!>id(fun String.(x: String) {}), ")!>id(fun(x: String, y: String) {})) + select(id(fun String.(x: String) {}), id(fun(x: String, y: String) { }), { x: String -> this }) + select(id(fun String.(x: String) {}), id(fun(x: String, y: String) { }), { x -> this }) + select(id(fun String.(x: String) {}), id(fun(x: String, y: String) { }), { x: String, y: String -> x }) + // Convert to extension lambda is impossible because the lambda parameter types aren't specified explicitly + select(id(fun String.(x: String) {}), id(fun(x: String, y: String) { }), { x, y -> x }) + select(id(id(fun(x: String, y: String) { }), fun String.(x: String) {}), { x, y -> x }) + val x26: Int.(String) -> Int = fun (x: String) = 10 // it must be error, see KT-38439 + // Receiver must be specified in anonymous function declaration + val x27: Int.(String) -> Int = id(fun (x: String) = 10) + select(id Unit> {}, { x: Int, y: String -> x }) + + // Inferring lambda parameter types by partially specified parameter types of other lambdas + select(id { x, y -> x.inv() + y.toByte() }, { x: Int, y -> y.toByte() }, { x, y: Number -> x.inv() }) + select(id { x, y -> x.inv() + y.toByte() }, id { x: Int, y -> y.toByte() }, id { x, y: Number -> x.inv() }) + select({ x, y -> x.inv() + y.toByte() }, id { x: Int, y -> y.toByte() }, id { x, y: Number -> x.inv() }) + + // Inferring lambda parameter types by other specified lambda parameters; expected type is a functional type with type variables in parameter types + takeLambdas({ it }, { x: Int -> }, { x: Nothing -> x }) + takeLambdas({ it }, { } as (Int) -> Unit, { x: Nothing -> x }) + takeLambdas({ it }, { } as (Nothing) -> Unit, { x: Int -> x }) + takeLambdas({ it }, { } as (Int) -> Unit, { } as (Nothing) -> Unit) + + // Inferring lambda parameter types by other specified lambda parameters; expected type is a functional type with type variables in parameter types; dependent type parameters + takeLambdasWithDirectlyDependentTypeParameters({ it }, { it }, { x: Int -> x }) + takeLambdasWithDirectlyDependentTypeParameters({ it }, { x: Number -> x }, { x: Int -> x }) + takeLambdasWithInverselyDependentTypeParameters({ it }, { it }, { x: Int -> x }) + /* + * Interesting test case: variable can be fixed to different types randomly (`Int` or `Number`; it depends on variable fixation order) + * if in `TypeVariableDependencyInformationProvider` `hashSet` instead of `linkedSet` for `deepTypeVariableDependencies` and `shallowTypeVariableDependencies` will be used + */ + takeLambdasWithInverselyDependentTypeParameters({ it }, { x: Number -> x }, { x: Int -> x }) + + // Inferring lambda parameter types by subtypes of functional type + ")!>select(A2(), { a, b, c -> a; b; c }) + ")!>select(A3(), { it }, { a -> a }) + ")!>select(A3(), ")!>A3::foo1) + // Should be error as `A3::foo1` is `KFunction2`, but the remaining arguments are `KFuncion1` or `Function1` + ")!>select(A3(), ")!>A3::foo1, { a -> a }, { it -> it }) + // It's OK because `A3::foo2` is from companion of `A3` + ")!>select(A3(), ")!>A3::foo2, { a -> a }, { it -> it }) + & java.io.Serializable>")!>select(A4(), { x: Number -> "" }) + & java.io.Serializable>")!>select(A5(), { x: Number, y: Int -> "" }) + select(A2(), id { a, b, c -> a; b; c }) + ")!>select(id(A3()), { it }, { a -> a }) + ")!>select(A3(), id(")!>A3::foo1)) + ")!>select(A3(), ")!>A3::foo1, id { a -> a }, { it -> it }) + ")!>select(A3(), ")!>A3::foo1, { a -> a }, id { it -> it }) + ")!>select(id(A3()), id(")!>A3::foo1), { a -> a }, { it -> it }) + ")!>select(id(A3()), id(")!>A3::foo1), { a -> a }, id { it -> it }) + // If lambdas' parameters are specified explicitly, we don't report an error, because there is proper CST – Function + ")!>select(id(A3()), id(")!>A3::foo1), { a: Number -> a }) + ")!>select(id(A3()), id(")!>A3::foo1), id { a: Number -> a }) + select(A4(), id { x: Number -> x }) + ")!>select(id(A5()), id { x: Number, y: Int -> x;y }) + ")!>select(id(A5()), id { x, y -> x;y }) + >")!>select(id(")!>A5()), id { x: Number, y: Int -> x;y }) + val x55: Function2 = select(id(A5()), id { x, y -> x;y; 1f }) + + // Diffrerent lambda's parameters with proper CST + ")!>select({ x: Int -> }, { x: String -> }) + ")!>select({ x: Int -> }, { x: Int, y: Number -> }) + ")!>select(id { x: Int -> }, { x: String -> }) + ")!>select({ x: Int -> }, id { x: Int, y: Number -> }) + ")!>select(id { x: Int -> }, id { x: String -> }) + ")!>select(id { x: Int -> }, id { x: Int, y: Number -> }) + & java.io.Serializable>")!>select({ x: Int -> 1 }, { x: String -> "" }) + >")!>select({ x: Int -> 1 }, { x: Int, y: Number -> 1f }) + >")!>select(id { x: Int -> Inv(10) }, { x: String -> Inv("") }) + ")!>select({ x: Int -> TODO() }, id { x: Int, y: Number -> Any() }) + ")!>select(id { x: Int -> null }, id { x: String -> "" }) + ")!>select(id { x: Int -> 10 }, id { x: Int, y: Number -> TODO() }) + val x68: String.(String) -> String = select(id { x: String, y: String -> "10" }, id { x: String, y: String -> "TODO()" }) + + // Anonymous functions + val x69: (C) -> Unit = selectB({ it }, { }, id(fun (x) { x })) + select(id1(fun(it) { it.inv() }), id1 { x: Number -> TODO() }, id1(id2(::takeInt))) + select(id(fun (it) { it }), id(id<(Int) -> Unit> { x: Number -> Unit })) + select(id(fun (it) { it.inv() }), id<(Int) -> Unit> { }) + val x70: (Int) -> Unit = selectNumber(id(fun (it) { }), id {}, id {}) + val x71: String.() -> Unit = select(")!>id(fun String.() { }), ")!>id(fun(x: String) {})) + val x72: String.() -> Unit = select(fun String.() { }, fun(x: String) {}) // must be error + select(id(fun String.(x: String) {}), id(fun(x: String, y: String) { }), fun (x, y) { x;y }) + select(id Unit>(fun (x, y) {}), { x: Int, y: String -> x }) // receiver of anonymous function must be specified explicitly + select(id Unit>(fun Int.(y) {}), { x: Int, y: String -> x }) + ")!>select(A3(), fun (x) = "", { a -> a }) +}