[FIR] KT-54980 Fix resolvability of too few/too many type arguments

- If too few or too many type arguments were provided, they were all
  thrown away in `TypeArgumentMapping`,
  `FirCallCompletionResultsWriterTransformer`, and `KtFirCallResolver`.
  The fix handles type arguments of the wrong arity more gracefully.
  - Note for `TypeArgumentMapping`: Excess type arguments are not needed
    for candidate resolution. Excess type arguments are still resolved
    due to the handling in `FirCallCompletionResultsWriterTransformer`.
- Post-processing in `AllCandidatesResolver`: When all candidates are
  resolved in `AllCandidatesResolver.getAllCandidates`, the function
  builds a FIR file. During that resolution, the
  `generic<String, String>` call (in example
  `functionCallWithTooFewTypeArguments.kt`) is correctly marked as
  inapplicable, but the missing type argument is inferred as an error
  type. `firFile` then contains a function call
  `generic<String, String, ERROR>` instead of `generic<String, String>`.
  This call is still marked as inapplicable. Despite that, the
  *subsequent* resolution by
  `bodyResolveComponents.callResolve.collectAllCandidates` disregards
  the call's inapplicability and resolves successfully into an
  applicable candidate. This is because `CandidateFactory` doesn't make
  any guarantees for already inapplicable calls. The fix adds
  post-processing to `AllCandidatesResolver` to preserve candidate
  inapplicability.
- Most tests that this commit changes had slightly different results due
  to type arguments becoming resolvable.
- `wrongNumberOfTypeArguments.kt` and
  `wrongNumberOfArgumentsInTypeAliasConstructor.kt`:
  `ConeDiagnostic.toFirDiagnostics` prefers specific errors. Because
  `ARGUMENT_TYPE_MISMATCH` is specific and `INAPPLICABLE_CANDIDATE` is
  not, only the former is reported. I see no reason to pass an illegally
  typed argument in either test, so the change reduces the errors to
  `INAPPLICABLE_CANDIDATE`.
- `typeAliasSamAdapterConstructors2.fir.kt`: See KT-55007.
- Disable `mismatchTypeParameters` JS backend test due to its handling
  of excess type arguments. See KT-55250.

^KT-54980 fixed
This commit is contained in:
Marco Pennekamp
2022-11-21 19:15:50 +01:00
committed by teamcity
parent d6a9235d05
commit 5f554d0065
56 changed files with 721 additions and 37 deletions
@@ -1,2 +0,0 @@
val u = <!UNRESOLVED_REFERENCE!>Unresolved<!>::class
val g = <!UNRESOLVED_REFERENCE!>UnresolvedGeneric<!><UnresolvedTypeArg>::class
@@ -1,2 +1,3 @@
// FIR_IDENTICAL
val u = <!UNRESOLVED_REFERENCE!>Unresolved<!>::class
val g = <!UNRESOLVED_REFERENCE!>UnresolvedGeneric<!><<!UNRESOLVED_REFERENCE!>UnresolvedTypeArg<!>>::class
@@ -10,6 +10,6 @@ fun test1() {
fun test2() {
val m0 = java.util.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>HashMap<!>()
val m1 = java.util.<!INAPPLICABLE_CANDIDATE!>HashMap<!><<!CANNOT_INFER_PARAMETER_TYPE!>String<!>, <!CANNOT_INFER_PARAMETER_TYPE!>String<!>, String>()
val m2 = java.util.<!INAPPLICABLE_CANDIDATE!>HashMap<!><<!CANNOT_INFER_PARAMETER_TYPE!>String<!>>()
val m1 = java.util.<!INAPPLICABLE_CANDIDATE!>HashMap<!><String, String, String>()
val m2 = java.util.<!INAPPLICABLE_CANDIDATE!>HashMap<!><String>()
}
@@ -1,5 +1,5 @@
fun box(): String {
return <!INAPPLICABLE_CANDIDATE!>someFunction<!><<!CANNOT_INFER_PARAMETER_TYPE!>SomeEnum<!>>()
return <!INAPPLICABLE_CANDIDATE!>someFunction<!><SomeEnum>()
}
interface SomeInterface <V> {
@@ -6,4 +6,4 @@ class Outer {
fun nested() = Outer.Nested<Int>()
fun noArguments() = Outer.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>Nested<!>()
fun noArgumentsExpectedType(): Outer.Nested<String> = Outer.Nested()
fun manyArguments() = Outer.<!INAPPLICABLE_CANDIDATE!>Nested<!><<!CANNOT_INFER_PARAMETER_TYPE!>String<!>, Int>()
fun manyArguments() = Outer.<!INAPPLICABLE_CANDIDATE!>Nested<!><String, Int>()
@@ -1,3 +1,3 @@
//KT-13330 AssertionError: Illegal resolved call to variable with invoke
fun foo(exec: (String.() -> Unit)?) = "".<!INAPPLICABLE_CANDIDATE!>exec<!><caret>() // <caret> is test data tag here
fun foo(exec: (String.() -> Unit)?) = "".<!INAPPLICABLE_CANDIDATE!>exec<!><<!UNRESOLVED_REFERENCE!>caret<!>>() // <caret> is test data tag here
@@ -1 +1 @@
val unwrapped = <!UNRESOLVED_REFERENCE!>some<!><<!UNRESOLVED_REFERENCE!>sdf<!>()()<out Any>::unwrap
val unwrapped = <!UNRESOLVED_REFERENCE!>some<!><<!UNRESOLVED_REFERENCE!>sdf<!>()()<<!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>out Any<!>>::unwrap
@@ -3,12 +3,12 @@
fun <T> foo(t: T) = t
fun test1() {
<!INAPPLICABLE_CANDIDATE!>foo<!><Int, String>("")
<!INAPPLICABLE_CANDIDATE!>foo<!><Int, String>(0)
}
fun <T, R> bar(t: T, r: R) {}
fun test2() {
<!INAPPLICABLE_CANDIDATE!>bar<!><Int>("", "")
<!INAPPLICABLE_CANDIDATE!>bar<!><Int>(0, "")
}
@@ -3,12 +3,12 @@
fun <T> foo(t: T) = t
fun test1() {
foo<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int, String><!>("")
foo<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int, String><!>(0)
}
fun <T, R> bar(t: T, r: R) {}
fun test2() {
bar<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>("", "")
bar<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>(0, "")
}
@@ -20,10 +20,10 @@ val test2p2 = <!INAPPLICABLE_CANDIDATE!>P2<!><Int, Int>(1, 1)
val test3p2 = <!INAPPLICABLE_CANDIDATE!>P2<!><Int, Int, Int>(1, 1)
val test0pr = PR(1, "")
val test1pr = <!INAPPLICABLE_CANDIDATE!>PR<!><Int>(1, "")
val test1pr = <!INAPPLICABLE_CANDIDATE!>PR<!><Int>("", 1)
val test2pr = PR<Int, String>(<!ARGUMENT_TYPE_MISMATCH!>1<!>, <!ARGUMENT_TYPE_MISMATCH!>""<!>)
val test2pra = PR<String, Int>(1, "")
val test3pr = <!INAPPLICABLE_CANDIDATE!>P2<!><String, Int, Int>(1, "")
val test3pr = <!INAPPLICABLE_CANDIDATE!>PR<!><String, Int, Int>(1, "")
class Num<T : Number>(val x: T)
typealias N<T> = Num<T>
@@ -20,10 +20,10 @@ val test2p2 = P2<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int, Int><!>(1, 1)
val test3p2 = P2<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int, Int, Int><!>(1, 1)
val test0pr = PR(1, "")
val test1pr = PR<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>(1, "")
val test1pr = PR<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><Int><!>("", 1)
val test2pr = PR<Int, String>(<!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>, <!TYPE_MISMATCH!>""<!>)
val test2pra = PR<String, Int>(1, "")
val test3pr = P2<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><String, Int, Int><!>(1, "")
val test3pr = PR<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!><String, Int, Int><!>(1, "")
class Num<T : Number>(val x: T)
typealias N<T> = Num<T>
@@ -6,14 +6,14 @@ public val test0p2a: Pair<out kotlin.Any, out kotlin.Any>
public val test0pr: PR<kotlin.String, kotlin.Int> /* = Pair<kotlin.Int, kotlin.String> */
public val test1: P<kotlin.Int, kotlin.Int> /* = Pair<kotlin.Int, kotlin.Int> */
public val test1p2: P2<kotlin.Int> /* = Pair<kotlin.Int, kotlin.Int> */
public val test1pr: PR<kotlin.String, kotlin.Int> /* = Pair<kotlin.Int, kotlin.String> */
public val test1pr: PR<kotlin.Int, kotlin.String> /* = Pair<kotlin.String, kotlin.Int> */
public val test2: P<kotlin.Int, kotlin.Int> /* = Pair<kotlin.Int, kotlin.Int> */
public val test2p2: P2<kotlin.Int> /* = Pair<kotlin.Int, kotlin.Int> */
public val test2pr: PR<kotlin.Int, kotlin.String> /* = Pair<kotlin.String, kotlin.Int> */
public val test2pra: PR<kotlin.String, kotlin.Int> /* = Pair<kotlin.Int, kotlin.String> */
public val test3: P<kotlin.Int, kotlin.Int> /* = Pair<kotlin.Int, kotlin.Int> */
public val test3p2: P2<kotlin.Int> /* = Pair<kotlin.Int, kotlin.Int> */
public val test3pr: Pair<out kotlin.Any, out kotlin.Any>
public val test3pr: PR<kotlin.String, kotlin.Int> /* = Pair<kotlin.Int, kotlin.String> */
public val testMP0: MP<kotlin.Int> /* = MyPair<kotlin.String, kotlin.Int> */
public val testMP1: MP<kotlin.String> /* = MyPair<kotlin.String, kotlin.String> */
public val testMP2: MP<kotlin.String> /* = MyPair<kotlin.String, kotlin.String> */