[FIR] Create error candidate for completion instead of simple error reference

This commit is contained in:
Dmitriy Novozhilov
2020-06-11 15:17:21 +03:00
parent 7c57c4a2fb
commit d7ee168dff
37 changed files with 369 additions and 248 deletions
@@ -0,0 +1,19 @@
fun foo(x: Int) {}
interface A
interface B
interface C : A, B
fun bar(x: A) {}
fun bar(x: B) {}
fun test(c: C) {
// Argument mapping error
<!INAPPLICABLE_CANDIDATE!>foo<!>("")
// Ambiguity
<!AMBIGUITY!>bar<!>(c)
// Unresolved reference
<!UNRESOLVED_REFERENCE!>baz<!>()
}
@@ -0,0 +1,18 @@
FILE: errorCandidates.kt
public final fun foo(x: R|kotlin/Int|): R|kotlin/Unit| {
}
public abstract interface A : R|kotlin/Any| {
}
public abstract interface B : R|kotlin/Any| {
}
public abstract interface C : R|A|, R|B| {
}
public final fun bar(x: R|A|): R|kotlin/Unit| {
}
public final fun bar(x: R|B|): R|kotlin/Unit| {
}
public final fun test(c: R|C|): R|kotlin/Unit| {
<Inapplicable(INAPPLICABLE): [/foo]>#(String())
<Ambiguity: bar, [/bar, /bar]>#(R|<local>/c|)
<Unresolved name: baz>#()
}
@@ -272,12 +272,12 @@ digraph flowFromInplaceLambda_kt {
107 [label="Postponed enter to lambda"];
subgraph cluster_14 {
color=blue
126 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
128 [label="Access variable R|<local>/y|"];
129 [label="Function call: R|<local>/y|.<Unresolved name: inc>#()"];
130 [label="Access variable R|<local>/x|"];
131 [label="Type operator: (R|<local>/x| as R|kotlin/Int|)"];
127 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
124 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
126 [label="Access variable R|<local>/y|"];
127 [label="Function call: R|<local>/y|.<Unresolved name: inc>#()"];
128 [label="Access variable R|<local>/x|"];
129 [label="Type operator: (R|<local>/x| as R|kotlin/Int|)"];
125 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
108 [label="Postponed exit from lambda"];
109 [label="Function call: R|/myRun|<R|kotlin/Int|>(...)"];
@@ -287,38 +287,36 @@ digraph flowFromInplaceLambda_kt {
113 [label="Postponed enter to lambda"];
subgraph cluster_15 {
color=blue
132 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
134 [label="Access variable R|<local>/x|"];
135 [label="Function call: R|<local>/x|.<Unresolved name: inc>#()"];
136 [label="Access variable R|<local>/y|"];
137 [label="Function call: R|<local>/y|.R|kotlin/Int.inc|()"];
138 [label="Const: Int(1)"];
133 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
130 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
132 [label="Access variable R|<local>/x|"];
133 [label="Function call: R|<local>/x|.<Unresolved name: inc>#()"];
134 [label="Access variable R|<local>/y|"];
135 [label="Function call: R|<local>/y|.R|kotlin/Int.inc|()"];
136 [label="Const: Int(1)"];
131 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
114 [label="Postponed exit from lambda"];
115 [label="Function call: R|/myRun|<R|kotlin/Int|>(...)"];
116 [label="Function call: R|/select|<R|kotlin/Int|>(...)"];
117 [label="Variable declaration: lval a: R|kotlin/Int|"];
118 [label="Access variable R|<local>/x|"];
119 [label="Access variable R|<local>/x|"];
120 [label="Access variable R|<local>/x|"];
121 [label="Function call: <Inapplicable(INAPPLICABLE): [/takeInt]>#(...)"];
122 [label="Access variable R|<local>/y|"];
119 [label="Function call: <Inapplicable(INAPPLICABLE): [/takeInt]>#(...)"];
120 [label="Access variable R|<local>/y|"];
121 [label="Function call: R|/takeInt|(...)"];
122 [label="Access variable R|<local>/a|"];
123 [label="Function call: R|/takeInt|(...)"];
124 [label="Access variable R|<local>/a|"];
125 [label="Function call: R|/takeInt|(...)"];
106 [label="Exit function test_4" style="filled" fillcolor=red];
}
105 -> {107};
107 -> {108};
107 -> {126} [color=red];
107 -> {124} [color=red];
108 -> {109};
109 -> {110};
110 -> {111};
111 -> {112};
112 -> {113};
113 -> {114};
113 -> {132} [color=red];
113 -> {130} [color=red];
114 -> {115};
115 -> {116};
116 -> {117};
@@ -328,110 +326,108 @@ digraph flowFromInplaceLambda_kt {
120 -> {121};
121 -> {122};
122 -> {123};
123 -> {124};
124 -> {125};
125 -> {106};
126 -> {128};
123 -> {106};
124 -> {126};
126 -> {127};
127 -> {128};
128 -> {129};
129 -> {130};
130 -> {131};
131 -> {127};
132 -> {134};
129 -> {125};
130 -> {132};
132 -> {133};
133 -> {134};
134 -> {135};
135 -> {136};
136 -> {137};
137 -> {138};
138 -> {133};
136 -> {131};
subgraph cluster_16 {
color=red
139 [label="Enter function test_5" style="filled" fillcolor=red];
141 [label="Postponed enter to lambda"];
137 [label="Enter function test_5" style="filled" fillcolor=red];
139 [label="Postponed enter to lambda"];
subgraph cluster_17 {
color=blue
152 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
154 [label="Function call: R|/materialize|<R|kotlin/Int|>()"];
153 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
150 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
152 [label="Function call: R|/materialize|<R|kotlin/Int|>()"];
151 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
142 [label="Postponed exit from lambda"];
143 [label="Function call: R|kotlin/run|<R|kotlin/Int|>(...)"];
144 [label="Postponed enter to lambda"];
140 [label="Postponed exit from lambda"];
141 [label="Function call: R|kotlin/run|<R|kotlin/Int|>(...)"];
142 [label="Postponed enter to lambda"];
subgraph cluster_18 {
color=blue
155 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
157 [label="Function call: R|/materialize|<R|kotlin/Int|>()"];
156 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
153 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
155 [label="Function call: R|/materialize|<R|kotlin/Int|>()"];
154 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
145 [label="Postponed exit from lambda"];
146 [label="Function call: R|kotlin/run|<R|kotlin/Int|>(...)"];
148 [label="Call arguments union" style="filled" fillcolor=yellow];
147 [label="Function call: R|/select|<R|kotlin/Int|>(...)"];
149 [label="Variable declaration: lval x: R|kotlin/Int|"];
150 [label="Access variable R|<local>/x|"];
151 [label="Function call: R|/takeInt|(...)"];
140 [label="Exit function test_5" style="filled" fillcolor=red];
143 [label="Postponed exit from lambda"];
144 [label="Function call: R|kotlin/run|<R|kotlin/Int|>(...)"];
146 [label="Call arguments union" style="filled" fillcolor=yellow];
145 [label="Function call: R|/select|<R|kotlin/Int|>(...)"];
147 [label="Variable declaration: lval x: R|kotlin/Int|"];
148 [label="Access variable R|<local>/x|"];
149 [label="Function call: R|/takeInt|(...)"];
138 [label="Exit function test_5" style="filled" fillcolor=red];
}
139 -> {141};
141 -> {152};
141 -> {142} [color=red];
142 -> {143};
137 -> {139};
139 -> {150};
139 -> {140} [color=red];
140 -> {141};
141 -> {142};
142 -> {153};
142 -> {143} [color=red];
143 -> {144};
144 -> {155};
144 -> {145} [color=red];
145 -> {146};
146 -> {148};
147 -> {149};
148 -> {147};
149 -> {150};
150 -> {151};
151 -> {140};
152 -> {154};
153 -> {142} [color=green];
153 -> {148} [color=red];
154 -> {153};
155 -> {157};
156 -> {145} [color=green];
156 -> {148} [color=red];
157 -> {156};
144 -> {146};
145 -> {147};
146 -> {145};
147 -> {148};
148 -> {149};
149 -> {138};
150 -> {152};
151 -> {140} [color=green];
151 -> {146} [color=red];
152 -> {151};
153 -> {155};
154 -> {143} [color=green];
154 -> {146} [color=red];
155 -> {154};
subgraph cluster_19 {
color=red
158 [label="Enter function test_6" style="filled" fillcolor=red];
160 [label="Postponed enter to lambda"];
156 [label="Enter function test_6" style="filled" fillcolor=red];
158 [label="Postponed enter to lambda"];
subgraph cluster_20 {
color=blue
165 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
167 [label="Postponed enter to lambda"];
163 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
165 [label="Postponed enter to lambda"];
subgraph cluster_21 {
color=blue
170 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
172 [label="Function call: R|/materialize|<R|kotlin/String|>()"];
171 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
168 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
170 [label="Function call: R|/materialize|<R|kotlin/String|>()"];
169 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
168 [label="Postponed exit from lambda"];
169 [label="Function call: R|kotlin/run|<R|kotlin/String|>(...)"];
166 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
166 [label="Postponed exit from lambda"];
167 [label="Function call: R|kotlin/run|<R|kotlin/String|>(...)"];
164 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
161 [label="Postponed exit from lambda"];
162 [label="Function call: R|/myRun|<R|kotlin/String|>(...)"];
163 [label="Function call: R|/id|<R|kotlin/String|>(...)"];
164 [label="Variable declaration: lval x: R|kotlin/String|"];
159 [label="Exit function test_6" style="filled" fillcolor=red];
159 [label="Postponed exit from lambda"];
160 [label="Function call: R|/myRun|<R|kotlin/String|>(...)"];
161 [label="Function call: R|/id|<R|kotlin/String|>(...)"];
162 [label="Variable declaration: lval x: R|kotlin/String|"];
157 [label="Exit function test_6" style="filled" fillcolor=red];
}
158 -> {160};
156 -> {158};
158 -> {159};
158 -> {163} [color=red];
159 -> {160};
160 -> {161};
160 -> {165} [color=red];
161 -> {162};
162 -> {163};
163 -> {164};
164 -> {159};
165 -> {167};
167 -> {170};
167 -> {168} [color=red];
168 -> {169};
169 -> {166};
170 -> {172};
171 -> {168} [color=green];
172 -> {171};
162 -> {157};
163 -> {165};
165 -> {168};
165 -> {166} [color=red];
166 -> {167};
167 -> {164};
168 -> {170};
169 -> {166} [color=green];
170 -> {169};
}
@@ -14,7 +14,7 @@ FILE: CallBasedInExpressionGenerator.kt
private get(): R|kotlin/Boolean|
public final override fun generate(argument: R|ERROR CLASS: Symbol not found, for `StackValue`|): R|ERROR CLASS: Symbol not found, for `BranchedValue`| {
^generate R?C|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator.gen|(R|<local>/argument|).<Inapplicable(WRONG_RECEIVER): [kotlin/let]>#(<L> = let@fun <anonymous>(): R|ERROR CLASS: Can't resolve when expression| {
^generate this@R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator|.R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator.gen|(R|<local>/argument|).<Inapplicable(WRONG_RECEIVER): [kotlin/let]>#(<L> = let@fun <anonymous>(): <ERROR TYPE REF: Can't resolve when expression> {
^ when () {
this@R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator|.R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator.isInverted| -> {
<Unresolved name: Invert>#(<Unresolved name: it>#)
@@ -17,6 +17,6 @@ FILE: typeParameters2.kt
^foo R|<local>/t|
}
public final fun main(fooImpl: R|FooImpl|, fooBarImpl: R|FooBarImpl|): R|kotlin/Unit| {
lval a: <ERROR TYPE REF: Inapplicable(INAPPLICABLE): [/foo]> = <Inapplicable(INAPPLICABLE): [/foo]>#<R|FooImpl|>(R|<local>/fooBarImpl|)
lval a: <ERROR TYPE REF: Inapplicable(INAPPLICABLE): [/foo]> = <Inapplicable(INAPPLICABLE): [/foo]>#(R|<local>/fooBarImpl|)
lval b: R|Foo| = R|/foo|<R|Foo|>(R|<local>/fooImpl|)
}
@@ -29,7 +29,7 @@ FILE: lambdaArgInScopeFunction.kt
}
) }
R|<local>/lambda|.R|tests/_checkType/checkType|<R|() -> KotlinClass|>(<L> = checkType@fun R|tests/_checkType/Inv<kotlin/Function0<KotlinClass>?>|.<anonymous>(): R|kotlin/Unit| {
^ <Inapplicable(WRONG_RECEIVER): [tests/_checkType/_]>#<R|(kotlin/Unit) -> KotlinClass?|>()
^ <Inapplicable(WRONG_RECEIVER): [tests/_checkType/_]>#()
}
)
}
@@ -50,7 +50,7 @@ FILE: lambdaArgInScopeFunction.kt
}
)
R|<local>/lambda|.R|tests/_checkType/checkType|<R|() -> KotlinClass|>(<L> = checkType@fun R|tests/_checkType/Inv<kotlin/Function0<KotlinClass>>|.<anonymous>(): R|kotlin/Unit| {
^ <Inapplicable(WRONG_RECEIVER): [tests/_checkType/_]>#<R|(kotlin/Unit) -> KotlinClass?|>()
^ <Inapplicable(WRONG_RECEIVER): [tests/_checkType/_]>#()
}
)
}
@@ -29,11 +29,11 @@ FILE: KotlinClass.kt
}
)
R|<local>/invalidType|.R|tests/_checkType/checkType|<R|(JavaClass) -> kotlin/Boolean|>(<L> = checkType@fun R|tests/_checkType/Inv<kotlin/Function1<JavaClass, kotlin/Boolean>>|.<anonymous>(): R|kotlin/Unit| {
^ <Inapplicable(WRONG_RECEIVER): [tests/_checkType/_]>#<R|(kotlin/Nothing) -> kotlin/Boolean|>()
^ <Inapplicable(WRONG_RECEIVER): [tests/_checkType/_]>#()
}
)
R|/Case1.Case1|(R|<local>/javaClass|).R|/Case1.x|.R|tests/_checkType/checkType|<R|(KotlinClass) -> kotlin/Boolean|>(<L> = checkType@fun R|tests/_checkType/Inv<kotlin/Function1<KotlinClass, kotlin/Boolean>>|.<anonymous>(): R|kotlin/Unit| {
^ <Inapplicable(WRONG_RECEIVER): [tests/_checkType/_]>#<R|(kotlin/Nothing) -> kotlin/Boolean|>()
^ <Inapplicable(WRONG_RECEIVER): [tests/_checkType/_]>#()
}
)
}
@@ -122,11 +122,11 @@ FILE: KotlinClass.kt
}
)
R|<local>/invalidType|.R|tests/_checkType/checkType|<R|(KotlinClass) -> kotlin/Boolean|>(<L> = checkType@fun R|tests/_checkType/Inv<kotlin/Function1<KotlinClass, kotlin/Boolean>>|.<anonymous>(): R|kotlin/Unit| {
^ <Inapplicable(WRONG_RECEIVER): [tests/_checkType/_]>#<R|(kotlin/Nothing) -> kotlin/Boolean|>()
^ <Inapplicable(WRONG_RECEIVER): [tests/_checkType/_]>#()
}
)
R|/Case2.Case2|(R|<local>/kotlinClass|).R|/Case2.x|.R|tests/_checkType/checkType|<R|(KotlinClass) -> kotlin/Boolean|>(<L> = checkType@fun R|tests/_checkType/Inv<kotlin/Function1<KotlinClass, kotlin/Boolean>>|.<anonymous>(): R|kotlin/Unit| {
^ <Inapplicable(WRONG_RECEIVER): [tests/_checkType/_]>#<R|(kotlin/Nothing) -> kotlin/Boolean|>()
^ <Inapplicable(WRONG_RECEIVER): [tests/_checkType/_]>#()
}
)
}
@@ -38,12 +38,12 @@ FILE: kotlinSam.kt
}
)
R|/foo1|(R|<local>/f|)
<Inapplicable(INAPPLICABLE): [/foo2]>#(<L> = foo2@fun <anonymous>(x: R|ERROR CLASS: No type for parameter|): R|kotlin/Boolean| {
<Inapplicable(INAPPLICABLE): [/foo2]>#(<L> = foo2@fun <anonymous>(x: R|kotlin/Nothing|): R|kotlin/Boolean| {
^ CMP(>, R|<local>/x|.<Unresolved name: compareTo>#(Int(1)))
}
)
<Inapplicable(INAPPLICABLE): [/foo2]>#(R|<local>/f|)
<Inapplicable(INAPPLICABLE): [/foo3]>#(<L> = foo3@fun <anonymous>(x: R|ERROR CLASS: No type for parameter|): R|kotlin/Boolean| {
<Inapplicable(INAPPLICABLE): [/foo3]>#(<L> = foo3@fun <anonymous>(x: R|kotlin/Nothing|): R|kotlin/Boolean| {
^ CMP(>, R|<local>/x|.<Unresolved name: compareTo>#(Int(1)))
}
)
@@ -2,7 +2,7 @@ FILE: main.kt
public final fun foo(m: R|MyRunnable|): R|kotlin/Unit| {
}
public final fun main(): R|kotlin/Unit| {
Q|JavaUsage|.<Inapplicable(INAPPLICABLE): [/JavaUsage.foo]>#(<L> = foo@fun <anonymous>(x: R|ERROR CLASS: No type for parameter|): R|kotlin/Boolean| {
Q|JavaUsage|.<Inapplicable(INAPPLICABLE): [/JavaUsage.foo]>#(<L> = foo@fun <anonymous>(x: R|kotlin/Nothing|): R|kotlin/Boolean| {
^ CMP(>, R|<local>/x|.<Unresolved name: compareTo>#(Int(1)))
}
)
@@ -35,7 +35,7 @@ FILE: sealedClass.kt
}
public final object Second : R|WithPrivateConstructor| {
private constructor(): R|Second| {
super<R|WithPrivateConstructor|>(IntegerLiteral(0))
super<R|WithPrivateConstructor|>(Int(0))
}
}
@@ -12,5 +12,5 @@ FILE: implicitTypes.kt
^loop1 <Inapplicable(INAPPLICABLE): [/use]>#(::R|/loop2|)
}
public final fun loop2(): <ERROR TYPE REF: cycle> {
^loop2 R?C|/loop1|()
^loop2 R|/loop1|()
}
@@ -117,7 +117,7 @@ digraph delegateWithAnonymousObject_kt {
subgraph cluster_11 {
color=red
66 [label="Enter class IssuesListUserProfile" style="filled" fillcolor=red];
64 [label="Enter class IssuesListUserProfile" style="filled" fillcolor=red];
subgraph cluster_12 {
color=blue
48 [label="Enter function setter" style="filled" fillcolor=red];
@@ -144,36 +144,32 @@ digraph delegateWithAnonymousObject_kt {
57 [label="Postponed exit from lambda"];
58 [label="Function call: this@R|/IssuesListUserProfile|.R|/delegate|<R|IssuesListUserProfile|, R|IssuesListUserProfile|, R|IssueListView|>(...)"];
59 [label="Access variable this@R|/IssuesListUserProfile|"];
60 [label="Access variable this@R|/IssuesListUserProfile|"];
61 [label="Access variable this@R|/IssuesListUserProfile|"];
62 [label="Function call: this@R|/IssuesListUserProfile|.R|/delegate|<R|IssuesListUserProfile|, R|IssuesListUserProfile|, R|IssueListView|>(...).<Unresolved name: provideDelegate>#(...)"];
63 [label="Postponed enter to lambda"];
60 [label="Function call: this@R|/IssuesListUserProfile|.R|/delegate|<R|IssuesListUserProfile|, R|IssuesListUserProfile|, R|IssueListView|>(...).<Unresolved name: provideDelegate>#(...)"];
61 [label="Postponed enter to lambda"];
subgraph cluster_15 {
color=blue
21 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
23 [label="Exit anonymous object"];
22 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
64 [label="Postponed exit from lambda"];
65 [label="Function call: this@R|/IssuesListUserProfile|.R|/delegate|<R|IssuesListUserProfile|, R|IssuesListUserProfile|, R|IssueListView|>(...)"];
62 [label="Postponed exit from lambda"];
63 [label="Function call: this@R|/IssuesListUserProfile|.R|/delegate|<R|IssuesListUserProfile|, R|IssuesListUserProfile|, R|IssueListView|>(...)"];
55 [label="Exit property" style="filled" fillcolor=red];
}
67 [label="Exit class IssuesListUserProfile" style="filled" fillcolor=red];
65 [label="Exit class IssuesListUserProfile" style="filled" fillcolor=red];
}
66 -> {54} [color=green];
64 -> {54} [color=green];
54 -> {56};
55 -> {67} [color=green];
55 -> {65} [color=green];
56 -> {57};
57 -> {58};
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {62};
61 -> {21} [color=red];
62 -> {63};
63 -> {64};
63 -> {21} [color=red];
64 -> {65};
65 -> {55};
63 -> {55};
21 -> {23};
21 -> {24 27 32} [color=red];
23 -> {22};
@@ -7,19 +7,19 @@ FILE: simpleDelegatedToMap.kt
public final val map: R|kotlin/collections/MutableMap<kotlin/String, kotlin/Any>| = R|<local>/map|
public get(): R|kotlin/collections/MutableMap<kotlin/String, kotlin/Any>|
public final var foo: <ERROR TYPE REF: Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]>by R|<local>/map|
public get(): <ERROR TYPE REF: Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]> {
public final var foo: R|ERROR CLASS: Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]|by R|<local>/map|
public get(): R|ERROR CLASS: Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]| {
^ this@R|/C|.D|/C.foo|.<Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]>#(this@R|/C|, ::R|/C.foo|)
}
public set(<set-?>: <ERROR TYPE REF: Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]>): R|kotlin/Unit| {
public set(<set-?>: R|ERROR CLASS: Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]|): R|kotlin/Unit| {
this@R|/C|.D|/C.foo|.<Inapplicable(INAPPLICABLE): [kotlin/collections/setValue]>#(this@R|/C|, ::R|/C.foo|, R|<local>/foo|)
}
}
public final var bar: <ERROR TYPE REF: Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]>by R|kotlin/collections/hashMapOf|<R|kotlin/String|, R|kotlin/Any|>()
public get(): <ERROR TYPE REF: Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]> {
public final var bar: R|ERROR CLASS: Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]|by R|kotlin/collections/hashMapOf|<R|kotlin/String|, R|kotlin/Any|>()
public get(): R|ERROR CLASS: Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]| {
^ D|/bar|.<Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]>#(Null(null), ::R|/bar|)
}
public set(<set-?>: <ERROR TYPE REF: Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]>): R|kotlin/Unit| {
public set(<set-?>: R|ERROR CLASS: Ambiguity: getValue, [kotlin/collections/getValue, kotlin/collections/getValue, kotlin/collections/getValue]|): R|kotlin/Unit| {
D|/bar|.<Inapplicable(INAPPLICABLE): [kotlin/collections/setValue]>#(Null(null), ::R|/bar|, R|<local>/bar|)
}
@@ -614,6 +614,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/debugInfoCall.kt");
}
@TestMetadata("errorCandidates.kt")
public void testErrorCandidates() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/errorCandidates.kt");
}
@TestMetadata("extensionInvokeAfterSafeCall.kt")
public void testExtensionInvokeAfterSafeCall() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/extensionInvokeAfterSafeCall.kt");
@@ -614,6 +614,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/debugInfoCall.kt");
}
@TestMetadata("errorCandidates.kt")
public void testErrorCandidates() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/errorCandidates.kt");
}
@TestMetadata("extensionInvokeAfterSafeCall.kt")
public void testExtensionInvokeAfterSafeCall() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/extensionInvokeAfterSafeCall.kt");
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.isInner
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.buildExpressionStub
import org.jetbrains.kotlin.fir.expressions.builder.buildResolvedReifiedParameterReference
@@ -73,13 +74,14 @@ class FirCallResolver(
val nameReference = createResolvedNamedReference(
functionCall.calleeReference,
name,
result.info,
result.candidates,
result.applicability,
functionCall.explicitReceiver,
)
val resultExpression = functionCall.transformCalleeReference(StoreNameReference, nameReference)
val candidate = resultExpression.candidate()
val candidate = (nameReference as? FirNamedReferenceWithCandidate)?.candidate
// We need desugaring
val resultFunctionCall = if (candidate != null && candidate.callInfo != result.info) {
@@ -162,6 +164,7 @@ class FirCallResolver(
val nameReference = createResolvedNamedReference(
callee,
callee.name,
result.info,
reducedCandidates,
result.applicability,
qualifiedAccess.explicitReceiver,
@@ -284,11 +287,11 @@ class FirCallResolver(
constructorClassSymbol,
)
return callResolver.selectDelegatingConstructorCall(delegatedConstructorCall, name, result)
return callResolver.selectDelegatingConstructorCall(delegatedConstructorCall, name, result, callInfo)
}
private fun selectDelegatingConstructorCall(
call: FirDelegatedConstructorCall, name: Name, result: CandidateCollector,
call: FirDelegatedConstructorCall, name: Name, result: CandidateCollector, callInfo: CallInfo
): FirDelegatedConstructorCall {
val bestCandidates = result.bestCandidates()
val reducedCandidates = if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) {
@@ -300,6 +303,7 @@ class FirCallResolver(
val nameReference = createResolvedNamedReference(
call.calleeReference,
name,
callInfo,
reducedCandidates,
result.currentApplicability,
)
@@ -348,29 +352,31 @@ class FirCallResolver(
private fun createResolvedNamedReference(
reference: FirReference,
name: Name,
callInfo: CallInfo,
candidates: Collection<Candidate>,
applicability: CandidateApplicability,
explicitReceiver: FirExpression? = null,
): FirNamedReference {
val source = reference.source
return when {
candidates.isEmpty() -> buildErrorNamedReference {
this.source = source
diagnostic = ConeUnresolvedNameError(name)
}
candidates.isEmpty() -> buildErrorReference(
callInfo,
ConeUnresolvedNameError(name),
source,
name
)
applicability < CandidateApplicability.SYNTHETIC_RESOLVED -> {
buildErrorNamedReference {
this.source = source
diagnostic = ConeInapplicableCandidateError(
applicability,
candidates.map {
ConeInapplicableCandidateError.CandidateInfo(
it.symbol,
if (it.systemInitialized) it.system.diagnostics else emptyList(),
)
},
)
}
val diagnostic = ConeInapplicableCandidateError(
applicability,
candidates.map {
ConeInapplicableCandidateError.CandidateInfo(
it.symbol,
if (it.systemInitialized) it.system.diagnostics else emptyList(),
)
}
)
buildErrorReference(callInfo, diagnostic, source, name)
}
candidates.size == 1 -> {
val candidate = candidates.single()
@@ -396,10 +402,23 @@ class FirCallResolver(
}
FirNamedReferenceWithCandidate(source, name, candidate)
}
else -> buildErrorNamedReference {
this.source = source
diagnostic = ConeAmbiguityError(name, candidates.map { it.symbol })
}
else -> buildErrorReference(
callInfo,
ConeAmbiguityError(name, candidates.map { it.symbol }),
source,
name
)
}
}
private fun buildErrorReference(
callInfo: CallInfo,
diagnostic: ConeDiagnostic,
source: FirSourceElement?,
name: Name
): FirErrorReferenceWithCandidate {
val candidate = CandidateFactory(components, callInfo).createErrorCandidate(diagnostic)
resolutionStageRunner.processCandidate(candidate, stopOnFirstError = false)
return FirErrorReferenceWithCandidate(source, name, candidate, diagnostic)
}
}
@@ -35,8 +35,8 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
fun Candidate.resolveArgumentExpression(
csBuilder: ConstraintSystemBuilder,
argument: FirExpression,
expectedType: ConeKotlinType,
expectedTypeRef: FirTypeRef,
expectedType: ConeKotlinType?,
expectedTypeRef: FirTypeRef?,
sink: CheckerSink,
isReceiver: Boolean,
isDispatch: Boolean
@@ -73,7 +73,7 @@ fun Candidate.resolveArgumentExpression(
checkApplicabilityForArgumentType(
csBuilder,
StandardClassIds.Unit.constructClassLikeType(emptyArray(), isNullable = false),
expectedType.type,
expectedType?.type,
SimpleConstraintSystemConstraintPosition,
isReceiver = false,
isDispatch = false,
@@ -122,8 +122,8 @@ fun Candidate.resolveArgumentExpression(
private fun Candidate.resolveBlockArgument(
csBuilder: ConstraintSystemBuilder,
block: FirBlock,
expectedType: ConeKotlinType,
expectedTypeRef: FirTypeRef,
expectedType: ConeKotlinType?,
expectedTypeRef: FirTypeRef?,
sink: CheckerSink,
isReceiver: Boolean,
isDispatch: Boolean
@@ -133,7 +133,7 @@ private fun Candidate.resolveBlockArgument(
checkApplicabilityForArgumentType(
csBuilder,
block.typeRef.coneTypeUnsafe(),
expectedType.type,
expectedType?.type,
SimpleConstraintSystemConstraintPosition,
isReceiver = false,
isDispatch = false,
@@ -157,7 +157,7 @@ private fun Candidate.resolveBlockArgument(
fun Candidate.resolveSubCallArgument(
csBuilder: ConstraintSystemBuilder,
argument: FirResolvable,
expectedType: ConeKotlinType,
expectedType: ConeKotlinType?,
sink: CheckerSink,
isReceiver: Boolean,
isDispatch: Boolean,
@@ -210,7 +210,7 @@ private fun Candidate.checkApplicabilityForIntegerOperatorCall(sink: CheckerSink
fun Candidate.resolvePlainArgumentType(
csBuilder: ConstraintSystemBuilder,
argumentType: ConeKotlinType,
expectedType: ConeKotlinType,
expectedType: ConeKotlinType?,
sink: CheckerSink,
isReceiver: Boolean,
isDispatch: Boolean,
@@ -257,12 +257,13 @@ private fun Candidate.captureTypeFromExpressionOrNull(argumentType: ConeKotlinTy
private fun checkApplicabilityForArgumentType(
csBuilder: ConstraintSystemBuilder,
argumentType: ConeKotlinType,
expectedType: ConeKotlinType,
expectedType: ConeKotlinType?,
position: SimpleConstraintSystemConstraintPosition,
isReceiver: Boolean,
isDispatch: Boolean,
sink: CheckerSink
) {
if (expectedType == null) return
if (isReceiver && isDispatch) {
if (!expectedType.isNullable && argumentType.isMarkedNullable) {
sink.reportApplicability(CandidateApplicability.WRONG_RECEIVER)
@@ -288,7 +289,7 @@ private fun checkApplicabilityForArgumentType(
internal fun Candidate.resolveArgument(
argument: FirExpression,
parameter: FirValueParameter,
parameter: FirValueParameter?,
isReceiver: Boolean,
isSafeCall: Boolean,
sink: CheckerSink
@@ -299,14 +300,15 @@ internal fun Candidate.resolveArgument(
this.system.getBuilder(),
argument,
expectedType,
parameter.returnTypeRef,
parameter?.returnTypeRef,
sink,
isReceiver,
false
)
}
private fun Candidate.prepareExpectedType(session: FirSession, argument: FirExpression, parameter: FirValueParameter): ConeKotlinType {
private fun Candidate.prepareExpectedType(session: FirSession, argument: FirExpression, parameter: FirValueParameter?): ConeKotlinType? {
if (parameter == null) return null
if (parameter.returnTypeRef is FirILTTypeRefPlaceHolder) return argument.resultType.coneTypeUnsafe()
val basicExpectedType = argument.getExpectedType(session, parameter/*, LanguageVersionSettings*/)
val expectedType = getExpectedTypeWithSAMConversion(session, argument, basicExpectedType) ?: basicExpectedType
@@ -5,10 +5,19 @@
package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.builder.buildErrorFunction
import org.jetbrains.kotlin.fir.declarations.builder.buildErrorProperty
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
import org.jetbrains.kotlin.fir.returnExpressions
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirErrorFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirErrorPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
@@ -55,6 +64,51 @@ class CandidateFactory private constructor(
} ?: callInfo
)
}
fun createErrorCandidate(diagnostic: ConeDiagnostic): Candidate {
val symbol: AbstractFirBasedSymbol<*> = when (callInfo.callKind) {
CallKind.VariableAccess -> createErrorPropertySymbol(diagnostic)
CallKind.Function,
CallKind.DelegatingConstructorCall,
CallKind.CallableReference -> createErrorFunctionSymbol(diagnostic)
CallKind.SyntheticSelect -> throw IllegalStateException()
CallKind.SyntheticIdForCallableReferencesResolution -> throw IllegalStateException()
}
return Candidate(
symbol,
dispatchReceiverValue = null,
implicitExtensionReceiverValue = null,
explicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
bodyResolveComponents,
baseSystem,
callInfo
)
}
private fun createErrorFunctionSymbol(diagnostic: ConeDiagnostic): FirErrorFunctionSymbol {
return FirErrorFunctionSymbol().also {
buildErrorFunction {
session = this@CandidateFactory.bodyResolveComponents.session
resolvePhase = FirResolvePhase.BODY_RESOLVE
origin = FirDeclarationOrigin.Synthetic
this.diagnostic = diagnostic
symbol = it
}
}
}
private fun createErrorPropertySymbol(diagnostic: ConeDiagnostic): FirErrorPropertySymbol {
return FirErrorPropertySymbol(diagnostic).also {
buildErrorProperty {
session = this@CandidateFactory.bodyResolveComponents.session
resolvePhase = FirResolvePhase.BODY_RESOLVE
origin = FirDeclarationOrigin.Synthetic
name = FirErrorPropertySymbol.NAME
this.diagnostic = diagnostic
symbol = it
}
}
}
}
fun PostponedArgumentsAnalyzer.Context.addSubsystemFromExpression(statement: FirStatement) {
@@ -32,7 +32,11 @@ suspend inline fun CheckerSink.yieldApplicability(new: CandidateApplicability) {
yieldIfNeed()
}
class CheckerSinkImpl(override val components: InferenceComponents, var continuation: Continuation<Unit>? = null) : CheckerSink() {
class CheckerSinkImpl(
override val components: InferenceComponents,
var continuation: Continuation<Unit>? = null,
val stopOnFirstError: Boolean = true
) : CheckerSink() {
var current = CandidateApplicability.RESOLVED
private set
@@ -47,6 +51,6 @@ class CheckerSinkImpl(override val components: InferenceComponents, var continua
}
override val needYielding: Boolean
get() = current < CandidateApplicability.SYNTHETIC_RESOLVED
get() = stopOnFirstError && current < CandidateApplicability.SYNTHETIC_RESOLVED
}
@@ -7,16 +7,28 @@ package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.fir.FirImplementationDetail
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.name.Name
@OptIn(FirImplementationDetail::class)
class FirNamedReferenceWithCandidate(
open class FirNamedReferenceWithCandidate(
source: FirSourceElement?,
name: Name,
val candidate: Candidate
) : FirSimpleNamedReference(source, name, candidate.symbol) {
override val candidateSymbol: AbstractFirBasedSymbol<*>
get() = candidate.symbol
open val isError: Boolean get() = false
}
class FirErrorReferenceWithCandidate(
source: FirSourceElement?,
name: Name,
candidate: Candidate,
val diagnostic: ConeDiagnostic
) : FirNamedReferenceWithCandidate(source, name, candidate) {
override val isError: Boolean get() = true
}
@@ -13,8 +13,8 @@ import kotlin.coroutines.intrinsics.createCoroutineUnintercepted
import kotlin.coroutines.resume
class ResolutionStageRunner(val components: InferenceComponents) {
fun processCandidate(candidate: Candidate): CandidateApplicability {
val sink = CheckerSinkImpl(components)
fun processCandidate(candidate: Candidate, stopOnFirstError: Boolean = true): CandidateApplicability {
val sink = CheckerSinkImpl(components, stopOnFirstError = stopOnFirstError)
var finished = false
sink.continuation = suspend {
for (stage in candidate.callInfo.callKind.resolutionSequence) {
@@ -186,7 +186,8 @@ internal object CheckArguments : CheckerStage() {
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
val argumentMapping =
candidate.argumentMapping ?: throw IllegalStateException("Argument should be already mapped while checking arguments!")
for ((argument, parameter) in argumentMapping) {
for (argument in callInfo.arguments) {
val parameter = argumentMapping[argument]
candidate.resolveArgument(
argument,
parameter,
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.expressions.FirResolvable
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
import org.jetbrains.kotlin.fir.resolve.calls.candidate
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.transformers.FirCallCompletionResultsWriterTransformer
@@ -51,24 +52,9 @@ class FirCallCompleter(
fun <T> completeCall(call: T, expectedTypeRef: FirTypeRef?): CompletionResult<T>
where T : FirResolvable, T : FirStatement {
val typeRef = typeFromCallee(call)
if (typeRef.type is ConeKotlinErrorType) {
if (call is FirExpression) {
call.resultType = typeRef
}
val errorCall = if (call is FirFunctionCall) {
call.argumentList.transformArguments(
transformer,
ResolutionMode.WithExpectedType(typeRef.resolvedTypeFromPrototype(session.builtinTypes.nullableAnyType.type))
)
call
} else {
call
}
inferenceSession.addErrorCall(errorCall)
return CompletionResult(errorCall, true)
}
val candidate = call.candidate() ?: return CompletionResult(call, true)
val reference = call.calleeReference as? FirNamedReferenceWithCandidate ?: return CompletionResult(call, true)
val candidate = reference.candidate
val initialSubstitutor = candidate.substitutor
val initialType = initialSubstitutor.substituteOrSelf(typeRef.type)
@@ -38,8 +38,8 @@ fun ConeKotlinType.isSuspendFunctionType(session: FirSession): Boolean {
}
}
fun ConeKotlinType.receiverType(expectedTypeRef: FirTypeRef, session: FirSession): ConeKotlinType? {
if (isBuiltinFunctionalType(session) && expectedTypeRef.isExtensionFunctionType(session)) {
fun ConeKotlinType.receiverType(expectedTypeRef: FirTypeRef?, session: FirSession): ConeKotlinType? {
if (isBuiltinFunctionalType(session) && expectedTypeRef?.isExtensionFunctionType(session) == true) {
return ((this as ConeClassLikeType).fullyExpandedType(session).typeArguments.first() as ConeKotlinTypeProjection).type
}
return null
@@ -63,7 +63,7 @@ val FirAnonymousFunction.receiverType get() = receiverTypeRef?.coneTypeSafe<Cone
fun extractLambdaInfoFromFunctionalType(
expectedType: ConeKotlinType?,
expectedTypeRef: FirTypeRef,
expectedTypeRef: FirTypeRef?,
argument: FirAnonymousFunction,
returnTypeVariable: ConeTypeVariableForLambdaReturnType?,
components: BodyResolveComponents,
@@ -78,7 +78,7 @@ fun extractLambdaInfoFromFunctionalType(
val receiverType = argument.receiverType ?: expectedType.receiverType(expectedTypeRef, session)
val returnType = argument.returnType ?: expectedType.returnType(session) ?: return null
val parameters = extractLambdaParameters(expectedType, argument, expectedTypeRef.isExtensionFunctionType(session), session)
val parameters = extractLambdaParameters(expectedType, argument, expectedTypeRef?.isExtensionFunctionType(session) ?: false, session)
return ResolvedLambdaAtom(
argument,
@@ -19,11 +19,11 @@ fun Candidate.preprocessLambdaArgument(
csBuilder: ConstraintSystemBuilder,
argument: FirAnonymousFunction,
expectedType: ConeKotlinType?,
expectedTypeRef: FirTypeRef,
expectedTypeRef: FirTypeRef?,
forceResolution: Boolean = false,
returnTypeVariable: ConeTypeVariableForLambdaReturnType? = null
): PostponedResolvedAtom {
if (expectedType != null && !forceResolution && csBuilder.isTypeVariable(expectedType)) {
if (expectedType != null && expectedTypeRef != null && !forceResolution && csBuilder.isTypeVariable(expectedType)) {
return LambdaWithTypeVariableAsExpectedTypeAtom(argument, expectedType, expectedTypeRef, this)
}
@@ -47,7 +47,7 @@ fun Candidate.preprocessLambdaArgument(
fun Candidate.preprocessCallableReference(
argument: FirCallableReferenceAccess,
expectedType: ConeKotlinType
expectedType: ConeKotlinType?
) {
val lhs = bodyResolveComponents.doubleColonExpressionResolver.resolveDoubleColonLHS(argument)
postponedAtoms += ResolvedCallableReferenceAtom(argument, expectedType, lhs, bodyResolveComponents.session)
@@ -11,10 +11,12 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.buildVarargArgumentsExpression
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
import org.jetbrains.kotlin.fir.references.builder.buildResolvedCallableReference
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
import org.jetbrains.kotlin.fir.resolve.calls.FirErrorReferenceWithCandidate
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
import org.jetbrains.kotlin.fir.resolve.calls.varargElementType
import org.jetbrains.kotlin.fir.resolve.constructFunctionalTypeRef
@@ -36,6 +38,7 @@ import org.jetbrains.kotlin.fir.visitors.*
import org.jetbrains.kotlin.types.AbstractTypeApproximator
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.addToStdlib.runIf
import kotlin.math.min
class FirCallCompletionResultsWriterTransformer(
@@ -78,11 +81,7 @@ class FirCallCompletionResultsWriterTransformer(
val result = updatedQualifiedAccess
.transformCalleeReference(
StoreCalleeReference,
buildResolvedNamedReference {
source = calleeReference.source
name = calleeReference.name
resolvedSymbol = calleeReference.candidateSymbol
},
calleeReference.toResolvedReference(),
)
.transformDispatchReceiver(StoreReceiver, subCandidate.dispatchReceiverExpression())
.transformExtensionReceiver(StoreReceiver, subCandidate.extensionReceiverExpression()) as T
@@ -131,10 +130,13 @@ class FirCallCompletionResultsWriterTransformer(
}
else -> {
resultType = typeRef.substituteTypeRef(subCandidate)
result.argumentList.transformArguments(this, subCandidate.createArgumentsMapping())
subCandidate.handleVarargs(result.argumentList)
subCandidate.argumentMapping?.let {
result.replaceArgumentList(buildResolvedArgumentList(it))
val expectedArgumentsTypeMapping = runIf(!calleeReference.isError) { subCandidate.createArgumentsMapping() }
result.argumentList.transformArguments(this, expectedArgumentsTypeMapping)
if (!calleeReference.isError) {
subCandidate.handleVarargs(result.argumentList)
subCandidate.argumentMapping?.let {
result.replaceArgumentList(buildResolvedArgumentList(it))
}
}
result.transformExplicitReceiver(integerApproximator, null)
}
@@ -258,11 +260,7 @@ class FirCallCompletionResultsWriterTransformer(
val typeArguments = computeTypeArguments(variableAssignment, calleeReference.candidate)
return variableAssignment.transformCalleeReference(
StoreCalleeReference,
buildResolvedNamedReference {
source = calleeReference.source
name = calleeReference.name
resolvedSymbol = calleeReference.candidateSymbol
},
calleeReference.toResolvedReference(),
).transformExplicitReceiver(integerApproximator, null).apply {
replaceTypeArguments(typeArguments)
}.compose()
@@ -310,18 +308,17 @@ class FirCallCompletionResultsWriterTransformer(
delegatedConstructorCall.calleeReference as? FirNamedReferenceWithCandidate ?: return delegatedConstructorCall.compose()
val subCandidate = calleeReference.candidate
delegatedConstructorCall.argumentList.transformArguments(this, calleeReference.candidate.createArgumentsMapping())
subCandidate.handleVarargs(delegatedConstructorCall.argumentList)
subCandidate.argumentMapping?.let {
delegatedConstructorCall.replaceArgumentList(buildResolvedArgumentList(it))
val argumentsMapping = runIf(!calleeReference.isError) { calleeReference.candidate.createArgumentsMapping() }
delegatedConstructorCall.argumentList.transformArguments(this, argumentsMapping)
if (!calleeReference.isError) {
subCandidate.handleVarargs(delegatedConstructorCall.argumentList)
subCandidate.argumentMapping?.let {
delegatedConstructorCall.replaceArgumentList(buildResolvedArgumentList(it))
}
}
return delegatedConstructorCall.transformCalleeReference(
StoreCalleeReference,
buildResolvedNamedReference {
source = calleeReference.source
name = calleeReference.name
resolvedSymbol = calleeReference.candidateSymbol
},
calleeReference.toResolvedReference(),
).compose()
}
@@ -433,11 +430,7 @@ class FirCallCompletionResultsWriterTransformer(
return (syntheticCall.transformCalleeReference(
StoreCalleeReference,
buildResolvedNamedReference {
source = calleeReference.source
name = calleeReference.name
resolvedSymbol = calleeReference.candidateSymbol
},
calleeReference.toResolvedReference(),
) as D).compose()
}
@@ -449,6 +442,20 @@ class FirCallCompletionResultsWriterTransformer(
val expectedType = data?.getExpectedType(constExpression)
return constExpression.transform(integerApproximator, expectedType)
}
private fun FirNamedReferenceWithCandidate.toResolvedReference() = if (this is FirErrorReferenceWithCandidate) {
buildErrorNamedReference {
source = this@toResolvedReference.source
diagnostic = this@toResolvedReference.diagnostic
}
} else {
buildResolvedNamedReference {
source = this@toResolvedReference.source
name = this@toResolvedReference.name
resolvedSymbol = this@toResolvedReference.candidateSymbol
}
}
}
sealed class ExpectedArgumentType {
@@ -220,12 +220,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
// name.invoke() case
callCompleter.completeCall(resultExplicitReceiver, noExpectedType)
}
val completionResult = callCompleter.completeCall(resultExpression, expectedTypeRef)
if (completionResult.result.typeRef is FirErrorTypeRef) {
completionResult.result.argumentList.transformArguments(transformer, ResolutionMode.LambdaResolution(null))
}
completionResult
callCompleter.completeCall(resultExpression, expectedTypeRef)
} catch (e: ProcessCanceledException) {
throw e
} catch (e: Throwable) {
@@ -2,7 +2,7 @@
fun foo() {
fun bar1() = bar1()
fun bar2() = 1 + bar2()
fun bar2() = 1 <!AMBIGUITY!>+<!> bar2()
fun bar3() = <!INAPPLICABLE_CANDIDATE!>id<!>(bar3())
}
@@ -3,6 +3,6 @@
// See EA-76890 / KT-10843: NPE during analysis
fun lambda(x : Int?) = x?.<!UNRESOLVED_REFERENCE!>let<!> <!UNRESOLVED_REFERENCE!>l<!> {
y ->
if (y > 0) return@l x
if (y <!UNRESOLVED_REFERENCE!>><!> 0) return@l x
y
}!!
@@ -52,4 +52,4 @@ FILE fqName:<root> fileName:/adaptedExtensionFunctions.kt
FUN name:testExtensionBoth visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [/use]>#' type=IrErrorType
FUNCTION_REFERENCE 'public final fun extensionBoth (i: kotlin.Int, s: kotlin.String, vararg t: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.reflect.KFunction3<<root>.C, kotlin.Int, kotlin.Array<out kotlin.String>, kotlin.Unit> origin=null reflectionTarget=<same>
FUNCTION_REFERENCE 'public final fun extensionBoth (i: kotlin.Int, s: kotlin.String, vararg t: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.reflect.KFunction4<<root>.C, kotlin.Int, kotlin.String, kotlin.Array<out kotlin.String>, kotlin.Unit> origin=null reflectionTarget=<same>
@@ -14,5 +14,5 @@ FILE fqName:test fileName:/boundInlineAdaptedReference.kt
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [test/foo]>#' type=IrErrorType
FUNCTION_REFERENCE 'public final fun id (s: kotlin.String, vararg xs: kotlin.Int): kotlin.String declared in test' type=kotlin.reflect.KFunction1<kotlin.IntArray, kotlin.String> origin=null reflectionTarget=<same>
FUNCTION_REFERENCE 'public final fun id (s: kotlin.String, vararg xs: kotlin.Int): kotlin.String declared in test' type=kotlin.reflect.KFunction2<kotlin.String, kotlin.IntArray, kotlin.String> origin=null reflectionTarget=<same>
$receiver: CONST String type=kotlin.String value="Fail"
@@ -80,7 +80,7 @@ FILE fqName:<root> fileName:/suspendConversion.kt
FUN name:testWithDefaults visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [/useSuspend]>#' type=IrErrorType
FUNCTION_REFERENCE 'public final fun foo4 (i: kotlin.Int): kotlin.Unit declared in <root>' type=kotlin.reflect.KFunction0<kotlin.Unit> origin=null reflectionTarget=<same>
FUNCTION_REFERENCE 'public final fun foo4 (i: kotlin.Int): kotlin.Unit declared in <root>' type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit> origin=null reflectionTarget=<same>
FUN name:testWithBoundReceiver visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [/useSuspend]>#' type=IrErrorType
@@ -5,10 +5,10 @@ FILE fqName:<root> fileName:/typeParametersInImplicitCast.kt
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun problematic <T> (lss: kotlin.collections.List<kotlin.collections.List<T of <root>.problematic>>): kotlin.collections.List<T of <root>.problematic> declared in <root>'
ERROR_CALL 'Unresolved reference: <Ambiguity: flatMap, [kotlin/collections/flatMap, kotlin/collections/flatMap]>#' type=IrErrorType
FUN_EXPR type=kotlin.Function0<kotlin.collections.List<kotlin.Nothing?>> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.collections.List<kotlin.Nothing?>
FUN_EXPR type=kotlin.Function0<kotlin.collections.List<kotlin.Any?>> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.collections.List<kotlin.Any?>
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.collections.List<kotlin.Nothing?> declared in <root>.problematic'
CALL 'public/*package*/ open fun id <T> (v: kotlin.collections.List<T of <root>.ListId.id?>?): kotlin.collections.List<T of <root>.ListId.id?> declared in <root>.ListId' type=kotlin.collections.List<kotlin.Nothing?> origin=null
<T>: kotlin.Nothing
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.collections.List<kotlin.Any?> declared in <root>.problematic'
CALL 'public/*package*/ open fun id <T> (v: kotlin.collections.List<T of <root>.ListId.id?>?): kotlin.collections.List<T of <root>.ListId.id?> declared in <root>.ListId' type=kotlin.collections.List<kotlin.Any?> origin=null
<T>: kotlin.Any?
v: ERROR_CALL 'Unresolved reference: <Unresolved name: it>#' type=IrErrorType
@@ -8,5 +8,5 @@ fun case_1(x: Interface2) = x
fun case_1() {
val x: Interface1 = null as Interface1
x as Interface2
<!AMBIGUITY!>case_1<!>(<!DEBUG_INFO_EXPRESSION_TYPE("Interface2 & Interface1 & Interface2 & Interface1")!>x<!>)
<!AMBIGUITY!>case_1<!>(<!DEBUG_INFO_EXPRESSION_TYPE("Interface2 & Interface1 & Interface1")!>x<!>)
}
@@ -37,7 +37,7 @@ fun case_2(x: Int?, y: Nothing?) {
fun case_3(x: Int?) {
if (x == null) {
x as Int
<!INAPPLICABLE_CANDIDATE!>stringArg<!>(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int & kotlin.Int")!>x<!>)
<!INAPPLICABLE_CANDIDATE!>stringArg<!>(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int & kotlin.Int?")!>x<!>)
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int & kotlin.Int?")!>x<!>
}
}
@@ -50,7 +50,7 @@ fun case_3(x: Int?) {
fun case_4(x: Int?) {
if (x == null) {
x!!
<!INAPPLICABLE_CANDIDATE!>stringArg<!>(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int & kotlin.Int")!>x<!>)
<!INAPPLICABLE_CANDIDATE!>stringArg<!>(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int & kotlin.Int?")!>x<!>)
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int & kotlin.Int?")!>x<!>
}
}
@@ -64,7 +64,7 @@ fun case_5(x: Int?) {
if (x == null) {
var y = x
y!!
<!INAPPLICABLE_CANDIDATE!>stringArg<!>(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int & kotlin.Int")!>y<!>)
<!INAPPLICABLE_CANDIDATE!>stringArg<!>(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int & kotlin.Int?")!>y<!>)
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int & kotlin.Int?")!>y<!>
}
}
@@ -298,7 +298,7 @@ fun case_12(a: ((Float) -> Int?)?, b: Float?, c: Boolean?) {
if (true && a == null == true || b == null == true) {
} else {
val x = <!DEBUG_INFO_EXPRESSION_TYPE("ERROR CLASS: Inapplicable(WRONG_RECEIVER): [kotlin/Function1.invoke]")!><!INAPPLICABLE_CANDIDATE!>a<!>(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Float & kotlin.Float")!>b<!>)<!>
val x = <!DEBUG_INFO_EXPRESSION_TYPE("ERROR CLASS: Inapplicable(WRONG_RECEIVER): [kotlin/Function1.invoke]")!><!INAPPLICABLE_CANDIDATE!>a<!>(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Float & kotlin.Float?")!>b<!>)<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.Float, kotlin.Int?>?")!>a<!>.<!INAPPLICABLE_CANDIDATE!>equals<!>(null)
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.Float, kotlin.Int?>?")!>a<!>.propT
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.Float, kotlin.Int?>?")!>a<!>.<!INAPPLICABLE_CANDIDATE!>propAny<!>
@@ -161,4 +161,6 @@ inline fun <T, R> Iterable<T>.same(extractor: (T) -> R): Boolean {
}
}
return true
}
}
inline fun <R> runIf(condition: Boolean, block: () -> R): R? = if (condition) block() else null