[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
@@ -297,6 +297,30 @@ public class Fe10IdeNormalAnalysisSourceModuleResolveCandidatesTestGenerated ext
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/functionCallWithSpreadArgument.kt");
}
@Test
@TestMetadata("functionCallWithTooFewTypeArguments.kt")
public void testFunctionCallWithTooFewTypeArguments() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/functionCallWithTooFewTypeArguments.kt");
}
@Test
@TestMetadata("functionCallWithTooFewTypeArguments2.kt")
public void testFunctionCallWithTooFewTypeArguments2() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/functionCallWithTooFewTypeArguments2.kt");
}
@Test
@TestMetadata("functionCallWithTooManyTypeArguments.kt")
public void testFunctionCallWithTooManyTypeArguments() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/functionCallWithTooManyTypeArguments.kt");
}
@Test
@TestMetadata("functionCallWithTooManyTypeArguments2.kt")
public void testFunctionCallWithTooManyTypeArguments2() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/functionCallWithTooManyTypeArguments2.kt");
}
@Test
@TestMetadata("functionCallWithTypeArgument.kt")
public void testFunctionCallWithTypeArgument() throws Exception {
@@ -622,6 +622,48 @@ public class Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exte
runTest("analysis/analysis-api/testData/referenceResolve/TypeArgumentBeforeDot.kt");
}
@Test
@TestMetadata("typeArgument_tooFewTypeArguments1.kt")
public void testTypeArgument_tooFewTypeArguments1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooFewTypeArguments1.kt");
}
@Test
@TestMetadata("typeArgument_tooFewTypeArguments1a.kt")
public void testTypeArgument_tooFewTypeArguments1a() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooFewTypeArguments1a.kt");
}
@Test
@TestMetadata("typeArgument_tooFewTypeArguments2.kt")
public void testTypeArgument_tooFewTypeArguments2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooFewTypeArguments2.kt");
}
@Test
@TestMetadata("typeArgument_tooManyTypeArguments1.kt")
public void testTypeArgument_tooManyTypeArguments1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooManyTypeArguments1.kt");
}
@Test
@TestMetadata("typeArgument_tooManyTypeArguments1a.kt")
public void testTypeArgument_tooManyTypeArguments1a() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooManyTypeArguments1a.kt");
}
@Test
@TestMetadata("typeArgument_tooManyTypeArguments2.kt")
public void testTypeArgument_tooManyTypeArguments2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooManyTypeArguments2.kt");
}
@Test
@TestMetadata("typeArgument_tooManyTypeArguments2a.kt")
public void testTypeArgument_tooManyTypeArguments2a() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooManyTypeArguments2a.kt");
}
@Test
@TestMetadata("ValueParameter.kt")
public void testValueParameter() throws Exception {
@@ -30,8 +30,8 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.resolver.AllCandidatesRes
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirEntry
import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment
import org.jetbrains.kotlin.analysis.utils.errors.rethrowExceptionWithDetails
import org.jetbrains.kotlin.analysis.utils.errors.withPsiEntry
import org.jetbrains.kotlin.analysis.utils.errors.rethrowExceptionWithDetails
import org.jetbrains.kotlin.analysis.utils.printer.parentOfType
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
@@ -798,21 +798,29 @@ internal class KtFirCallResolver(
return toTypeArgumentsMapping(typeArguments, partiallyAppliedSymbol)
}
/**
* Maps [typeArguments] to the type parameters of [partiallyAppliedSymbol].
*
* If too many type arguments are provided, a mapping is still created. Extra type arguments are simply ignored. If this wasn't the
* case, the resulting [KtCall] would contain no type arguments at all, which can cause problems later. If too few type arguments are
* provided, an empty map is returned defensively so that [toTypeArgumentsMapping] doesn't conjure any error types. If you want to map
* too few type arguments meaningfully, please provide filler types explicitly.
*/
private fun toTypeArgumentsMapping(
typeArguments: List<FirTypeProjection>,
partiallyAppliedSymbol: KtPartiallyAppliedSymbol<*, *>
): Map<KtTypeParameterSymbol, KtType> {
val typeParameters = partiallyAppliedSymbol.symbol.typeParameters
if (typeParameters.isEmpty()) return emptyMap()
if (typeParameters.size != typeArguments.size) return emptyMap()
if (typeArguments.size < typeParameters.size) return emptyMap()
val result = mutableMapOf<KtTypeParameterSymbol, KtType>()
for ((index, argument) in typeArguments.withIndex()) {
for ((index, typeParameter) in typeParameters.withIndex()) {
// After resolution all type arguments should be usual types (not FirPlaceholderProjection)
if (argument !is FirTypeProjectionWithVariance || argument.variance != Variance.INVARIANT) return emptyMap()
val argumentKtType = argument.typeRef.coneType.asKtType()
result[typeParameters[index]] = argumentKtType
val typeArgument = typeArguments[index]
if (typeArgument !is FirTypeProjectionWithVariance || typeArgument.variance != Variance.INVARIANT) return emptyMap()
result[typeParameter] = typeArgument.typeRef.coneType.asKtType()
}
return result
@@ -297,6 +297,30 @@ public class FirIdeNormalAnalysisSourceModuleResolveCandidatesTestGenerated exte
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/functionCallWithSpreadArgument.kt");
}
@Test
@TestMetadata("functionCallWithTooFewTypeArguments.kt")
public void testFunctionCallWithTooFewTypeArguments() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/functionCallWithTooFewTypeArguments.kt");
}
@Test
@TestMetadata("functionCallWithTooFewTypeArguments2.kt")
public void testFunctionCallWithTooFewTypeArguments2() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/functionCallWithTooFewTypeArguments2.kt");
}
@Test
@TestMetadata("functionCallWithTooManyTypeArguments.kt")
public void testFunctionCallWithTooManyTypeArguments() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/functionCallWithTooManyTypeArguments.kt");
}
@Test
@TestMetadata("functionCallWithTooManyTypeArguments2.kt")
public void testFunctionCallWithTooManyTypeArguments2() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/functionCallWithTooManyTypeArguments2.kt");
}
@Test
@TestMetadata("functionCallWithTypeArgument.kt")
public void testFunctionCallWithTypeArgument() throws Exception {
@@ -622,6 +622,48 @@ public class FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated ex
runTest("analysis/analysis-api/testData/referenceResolve/TypeArgumentBeforeDot.kt");
}
@Test
@TestMetadata("typeArgument_tooFewTypeArguments1.kt")
public void testTypeArgument_tooFewTypeArguments1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooFewTypeArguments1.kt");
}
@Test
@TestMetadata("typeArgument_tooFewTypeArguments1a.kt")
public void testTypeArgument_tooFewTypeArguments1a() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooFewTypeArguments1a.kt");
}
@Test
@TestMetadata("typeArgument_tooFewTypeArguments2.kt")
public void testTypeArgument_tooFewTypeArguments2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooFewTypeArguments2.kt");
}
@Test
@TestMetadata("typeArgument_tooManyTypeArguments1.kt")
public void testTypeArgument_tooManyTypeArguments1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooManyTypeArguments1.kt");
}
@Test
@TestMetadata("typeArgument_tooManyTypeArguments1a.kt")
public void testTypeArgument_tooManyTypeArguments1a() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooManyTypeArguments1a.kt");
}
@Test
@TestMetadata("typeArgument_tooManyTypeArguments2.kt")
public void testTypeArgument_tooManyTypeArguments2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooManyTypeArguments2.kt");
}
@Test
@TestMetadata("typeArgument_tooManyTypeArguments2a.kt")
public void testTypeArgument_tooManyTypeArguments2a() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooManyTypeArguments2a.kt");
}
@Test
@TestMetadata("ValueParameter.kt")
public void testValueParameter() throws Exception {
@@ -622,6 +622,48 @@ public class FirIdeNormalAnalysisLibrarySourceModuleReferenceResolveTestGenerate
runTest("analysis/analysis-api/testData/referenceResolve/TypeArgumentBeforeDot.kt");
}
@Test
@TestMetadata("typeArgument_tooFewTypeArguments1.kt")
public void testTypeArgument_tooFewTypeArguments1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooFewTypeArguments1.kt");
}
@Test
@TestMetadata("typeArgument_tooFewTypeArguments1a.kt")
public void testTypeArgument_tooFewTypeArguments1a() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooFewTypeArguments1a.kt");
}
@Test
@TestMetadata("typeArgument_tooFewTypeArguments2.kt")
public void testTypeArgument_tooFewTypeArguments2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooFewTypeArguments2.kt");
}
@Test
@TestMetadata("typeArgument_tooManyTypeArguments1.kt")
public void testTypeArgument_tooManyTypeArguments1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooManyTypeArguments1.kt");
}
@Test
@TestMetadata("typeArgument_tooManyTypeArguments1a.kt")
public void testTypeArgument_tooManyTypeArguments1a() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooManyTypeArguments1a.kt");
}
@Test
@TestMetadata("typeArgument_tooManyTypeArguments2.kt")
public void testTypeArgument_tooManyTypeArguments2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooManyTypeArguments2.kt");
}
@Test
@TestMetadata("typeArgument_tooManyTypeArguments2a.kt")
public void testTypeArgument_tooManyTypeArguments2a() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooManyTypeArguments2a.kt");
}
@Test
@TestMetadata("ValueParameter.kt")
public void testValueParameter() throws Exception {
@@ -622,6 +622,48 @@ public class FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exten
runTest("analysis/analysis-api/testData/referenceResolve/TypeArgumentBeforeDot.kt");
}
@Test
@TestMetadata("typeArgument_tooFewTypeArguments1.kt")
public void testTypeArgument_tooFewTypeArguments1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooFewTypeArguments1.kt");
}
@Test
@TestMetadata("typeArgument_tooFewTypeArguments1a.kt")
public void testTypeArgument_tooFewTypeArguments1a() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooFewTypeArguments1a.kt");
}
@Test
@TestMetadata("typeArgument_tooFewTypeArguments2.kt")
public void testTypeArgument_tooFewTypeArguments2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooFewTypeArguments2.kt");
}
@Test
@TestMetadata("typeArgument_tooManyTypeArguments1.kt")
public void testTypeArgument_tooManyTypeArguments1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooManyTypeArguments1.kt");
}
@Test
@TestMetadata("typeArgument_tooManyTypeArguments1a.kt")
public void testTypeArgument_tooManyTypeArguments1a() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooManyTypeArguments1a.kt");
}
@Test
@TestMetadata("typeArgument_tooManyTypeArguments2.kt")
public void testTypeArgument_tooManyTypeArguments2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooManyTypeArguments2.kt");
}
@Test
@TestMetadata("typeArgument_tooManyTypeArguments2a.kt")
public void testTypeArgument_tooManyTypeArguments2a() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooManyTypeArguments2a.kt");
}
@Test
@TestMetadata("ValueParameter.kt")
public void testValueParameter() throws Exception {
@@ -297,6 +297,30 @@ public class FirStandaloneNormalAnalysisSourceModuleResolveCandidatesTestGenerat
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/functionCallWithSpreadArgument.kt");
}
@Test
@TestMetadata("functionCallWithTooFewTypeArguments.kt")
public void testFunctionCallWithTooFewTypeArguments() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/functionCallWithTooFewTypeArguments.kt");
}
@Test
@TestMetadata("functionCallWithTooFewTypeArguments2.kt")
public void testFunctionCallWithTooFewTypeArguments2() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/functionCallWithTooFewTypeArguments2.kt");
}
@Test
@TestMetadata("functionCallWithTooManyTypeArguments.kt")
public void testFunctionCallWithTooManyTypeArguments() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/functionCallWithTooManyTypeArguments.kt");
}
@Test
@TestMetadata("functionCallWithTooManyTypeArguments2.kt")
public void testFunctionCallWithTooManyTypeArguments2() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/functionCallWithTooManyTypeArguments2.kt");
}
@Test
@TestMetadata("functionCallWithTypeArgument.kt")
public void testFunctionCallWithTypeArgument() throws Exception {
@@ -622,6 +622,48 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerate
runTest("analysis/analysis-api/testData/referenceResolve/TypeArgumentBeforeDot.kt");
}
@Test
@TestMetadata("typeArgument_tooFewTypeArguments1.kt")
public void testTypeArgument_tooFewTypeArguments1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooFewTypeArguments1.kt");
}
@Test
@TestMetadata("typeArgument_tooFewTypeArguments1a.kt")
public void testTypeArgument_tooFewTypeArguments1a() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooFewTypeArguments1a.kt");
}
@Test
@TestMetadata("typeArgument_tooFewTypeArguments2.kt")
public void testTypeArgument_tooFewTypeArguments2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooFewTypeArguments2.kt");
}
@Test
@TestMetadata("typeArgument_tooManyTypeArguments1.kt")
public void testTypeArgument_tooManyTypeArguments1() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooManyTypeArguments1.kt");
}
@Test
@TestMetadata("typeArgument_tooManyTypeArguments1a.kt")
public void testTypeArgument_tooManyTypeArguments1a() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooManyTypeArguments1a.kt");
}
@Test
@TestMetadata("typeArgument_tooManyTypeArguments2.kt")
public void testTypeArgument_tooManyTypeArguments2() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooManyTypeArguments2.kt");
}
@Test
@TestMetadata("typeArgument_tooManyTypeArguments2a.kt")
public void testTypeArgument_tooManyTypeArguments2a() throws Exception {
runTest("analysis/analysis-api/testData/referenceResolve/typeArgument_tooManyTypeArguments2a.kt");
}
@Test
@TestMetadata("ValueParameter.kt")
public void testValueParameter() throws Exception {
@@ -71,7 +71,10 @@ KtInapplicableCallCandidateInfo:
callableIdIfNonLocal = null
]
callableIdIfNonLocal = kotlin/collections/groupBy
typeArgumentsMapping = {}
typeArgumentsMapping = {
T -> (kotlin.collections.IndexedValue<kotlin.Int>),
K -> (kotlin.Int)
}
argumentMapping = {
{ (_, value) -> value } -> (KtVariableLikeSignature:
name = keySelector
@@ -111,7 +114,9 @@ KtInapplicableCallCandidateInfo:
callableIdIfNonLocal = null
]
callableIdIfNonLocal = /groupBy
typeArgumentsMapping = {}
typeArgumentsMapping = {
K -> (kotlin.collections.IndexedValue<kotlin.Int>)
}
argumentMapping = {
{ (_, value) -> value } -> (KtVariableLikeSignature:
name = keySelector
@@ -0,0 +1,20 @@
KtInapplicableCallCandidateInfo:
diagnostic = ERROR<null: OTHER_ERROR with generic>
candidate = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /generic(): kotlin.Unit
valueParameters = []
callableIdIfNonLocal = /generic
typeArgumentsMapping = {
A -> (ERROR_TYPE),
B -> (ERROR_TYPE),
C -> (ERROR_TYPE)
}
argumentMapping = {}
isInBestCandidates = true
@@ -0,0 +1,5 @@
fun <A, B, C> generic() { }
fun foo() {
<expr>generic<String, String>()</expr>
}
@@ -0,0 +1,20 @@
KtInapplicableCallCandidateInfo:
diagnostic = ERROR<INAPPLICABLE_CANDIDATE: Inapplicable candidate(s): fun <A, B, C> generic(): Unit>
candidate = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /generic(): kotlin.Unit
valueParameters = []
callableIdIfNonLocal = /generic
typeArgumentsMapping = {
A -> (kotlin.String),
B -> (kotlin.String),
C -> (ERROR CLASS: Cannot infer argument for type parameter C)
}
argumentMapping = {}
isInBestCandidates = true
@@ -0,0 +1,58 @@
KtInapplicableCallCandidateInfo:
diagnostic = ERROR<null: OTHER_ERROR with generic>
candidate = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /generic(a: A, b: B, c: C): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.String
symbol = a: A
callableIdIfNonLocal = null,
KtVariableLikeSignature:
name = b
receiverType = null
returnType = kotlin.String
symbol = b: B
callableIdIfNonLocal = null,
KtVariableLikeSignature:
name = c
receiverType = null
returnType = kotlin.String
symbol = c: C
callableIdIfNonLocal = null
]
callableIdIfNonLocal = /generic
typeArgumentsMapping = {
A -> (kotlin.String),
B -> (kotlin.String),
C -> (kotlin.String)
}
argumentMapping = {
"a" -> (KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.String
symbol = a: A
callableIdIfNonLocal = null),
"b" -> (KtVariableLikeSignature:
name = b
receiverType = null
returnType = kotlin.String
symbol = b: B
callableIdIfNonLocal = null),
"c" -> (KtVariableLikeSignature:
name = c
receiverType = null
returnType = kotlin.String
symbol = c: C
callableIdIfNonLocal = null)
}
isInBestCandidates = true
@@ -0,0 +1,5 @@
fun <A, B, C> generic(a: A, b: B, c: C) { }
fun foo() {
<expr>generic<String, String>("a", "b", "c")</expr>
}
@@ -0,0 +1,58 @@
KtInapplicableCallCandidateInfo:
diagnostic = ERROR<INAPPLICABLE_CANDIDATE: Inapplicable candidate(s): fun <A, B, C> generic(a: A, b: B, c: C): Unit>
candidate = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /generic(a: A, b: B, c: C): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.String
symbol = a: A
callableIdIfNonLocal = null,
KtVariableLikeSignature:
name = b
receiverType = null
returnType = kotlin.String
symbol = b: B
callableIdIfNonLocal = null,
KtVariableLikeSignature:
name = c
receiverType = null
returnType = kotlin.String
symbol = c: C
callableIdIfNonLocal = null
]
callableIdIfNonLocal = /generic
typeArgumentsMapping = {
A -> (kotlin.String),
B -> (kotlin.String),
C -> (kotlin.String)
}
argumentMapping = {
"a" -> (KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.String
symbol = a: A
callableIdIfNonLocal = null),
"b" -> (KtVariableLikeSignature:
name = b
receiverType = null
returnType = kotlin.String
symbol = b: B
callableIdIfNonLocal = null),
"c" -> (KtVariableLikeSignature:
name = c
receiverType = null
returnType = kotlin.String
symbol = c: C
callableIdIfNonLocal = null)
}
isInBestCandidates = true
@@ -0,0 +1,18 @@
KtInapplicableCallCandidateInfo:
diagnostic = ERROR<null: OTHER_ERROR with generic>
candidate = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /generic(): kotlin.Unit
valueParameters = []
callableIdIfNonLocal = /generic
typeArgumentsMapping = {
A -> (ERROR_TYPE)
}
argumentMapping = {}
isInBestCandidates = true
@@ -0,0 +1,5 @@
fun <A> generic() { }
fun foo() {
<expr>generic<String, String>()</expr>
}
@@ -0,0 +1,18 @@
KtInapplicableCallCandidateInfo:
diagnostic = ERROR<INAPPLICABLE_CANDIDATE: Inapplicable candidate(s): fun <A> generic(): Unit>
candidate = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /generic(): kotlin.Unit
valueParameters = []
callableIdIfNonLocal = /generic
typeArgumentsMapping = {
A -> (kotlin.String)
}
argumentMapping = {}
isInBestCandidates = true
@@ -0,0 +1,32 @@
KtInapplicableCallCandidateInfo:
diagnostic = ERROR<null: OTHER_ERROR with generic>
candidate = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /generic(a: A): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Int
symbol = a: A
callableIdIfNonLocal = null
]
callableIdIfNonLocal = /generic
typeArgumentsMapping = {
A -> (kotlin.Int)
}
argumentMapping = {
5 -> (KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Int
symbol = a: A
callableIdIfNonLocal = null)
}
isInBestCandidates = true
@@ -0,0 +1,5 @@
fun <A> generic(a: A) { }
fun foo() {
<expr>generic<Int, String>(5)</expr>
}
@@ -0,0 +1,32 @@
KtInapplicableCallCandidateInfo:
diagnostic = ERROR<INAPPLICABLE_CANDIDATE: Inapplicable candidate(s): fun <A> generic(a: A): Unit>
candidate = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /generic(a: A): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Int
symbol = a: A
callableIdIfNonLocal = null
]
callableIdIfNonLocal = /generic
typeArgumentsMapping = {
A -> (kotlin.Int)
}
argumentMapping = {
5 -> (KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Int
symbol = a: A
callableIdIfNonLocal = null)
}
isInBestCandidates = true
@@ -0,0 +1,6 @@
// COMPILATION_ERRORS
fun <A, B, C> generic() { }
fun foo() {
generic<<caret>String, String>()
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in kotlin) class String : kotlin.Comparable<kotlin.String>, kotlin.CharSequence, java.io.Serializable
@@ -0,0 +1,8 @@
// COMPILATION_ERRORS
interface X
fun <A, B, C> generic() { }
fun foo() {
generic<String, <caret>X>()
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in ROOT) interface X
@@ -0,0 +1,6 @@
// COMPILATION_ERRORS
fun <A, B, C> generic(a: A, b: B, c: C) { }
fun foo() {
generic<<caret>String, String>("a", "b", "c")
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in kotlin) class String : kotlin.Comparable<kotlin.String>, kotlin.CharSequence, java.io.Serializable
@@ -0,0 +1,9 @@
// COMPILATION_ERRORS
interface X
interface Y
fun <A> generic() { }
fun foo() {
generic<X, <caret>Y>()
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in ROOT) interface Y
@@ -0,0 +1,9 @@
// COMPILATION_ERRORS
interface X
interface Y
fun <A> generic() { }
fun foo() {
generic<<caret>X, Y>()
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in ROOT) interface X
@@ -0,0 +1,8 @@
// COMPILATION_ERRORS
interface X
fun <A> generic(a: A) { }
fun foo() {
generic<Int, <caret>X>(5)
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in ROOT) interface X
@@ -0,0 +1,8 @@
// COMPILATION_ERRORS
interface X
fun <A> generic(a: A) { }
fun foo() {
generic<<caret>Int, X>(5)
}
@@ -0,0 +1,2 @@
Resolved to:
0: (in kotlin) class Intprivate constructor : kotlin.Number(), kotlin.Comparable<kotlin.Int>, java.io.Serializable
@@ -11,11 +11,15 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.resolveToFirSymbol
import org.jetbrains.kotlin.analysis.utils.printer.parentsOfType
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.calls.InapplicableCandidate
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionContext
import org.jetbrains.kotlin.fir.resolve.calls.tower.FirTowerResolver
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableCandidateError
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirExpressionsResolveTransformer
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
@@ -25,6 +29,7 @@ import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
class AllCandidatesResolver(private val firSession: FirSession) {
private val scopeSession = ScopeSession()
@@ -66,6 +71,7 @@ class AllCandidatesResolver(private val firSession: FirSession) {
return bodyResolveComponents.context.withFile(firFile, bodyResolveComponents) {
bodyResolveComponents.callResolver
.collectAllCandidates(functionCall, calleeName, bodyResolveComponents.context.containers, resolutionContext)
.apply { postProcessCandidates() }
}
}
@@ -84,6 +90,7 @@ class AllCandidatesResolver(private val firSession: FirSession) {
.resolveDelegatingConstructorCall(delegatedConstructorCall, constructedType, derivedClassLookupTag)
bodyResolveComponents.collector.allCandidates
.map { OverloadCandidate(it, isInBestCandidates = it in bodyResolveComponents.collector.bestCandidates()) }
.apply { postProcessCandidates() }
}
}
@@ -96,4 +103,28 @@ class AllCandidatesResolver(private val firSession: FirSession) {
element.parentsOfType<KtDeclaration>().map { it.resolveToFirSymbol(firResolveSession).fir }.toList().asReversed()
bodyResolveComponents.context.containers.addAll(containingDeclarations)
}
private fun List<OverloadCandidate>.postProcessCandidates() {
forEach { it.preserveCalleeInapplicability() }
}
/**
* Post-processes a candidate to carry the callee's inapplicability over into the candidate. Without this post-processing, an issue may
* arise where [getAllCandidates] produces "applicable" candidates with inapplicable callee references.
*
* For example, a function call `generic<String, String>` of function `fun <A, B, C> generic() { }` is correctly marked as inapplicable
* by the compiler (due to the missing type argument), but the `firFile` built during [getAllCandidates] will contain an inapplicable
* function call `generic<String, String, ERROR>` (with the missing type argument inferred as an error type). The *subsequent*
* resolution by `bodyResolveComponents.callResolver.collectAllCandidates` feeds this call to
* [org.jetbrains.kotlin.fir.resolve.calls.CandidateFactory], which doesn't make any guarantees for inapplicable calls. Hence, the
* resulting candidate is *not* marked as inapplicable and needs to be post-processed.
*/
private fun OverloadCandidate.preserveCalleeInapplicability() {
val callSite = candidate.callInfo.callSite as? FirQualifiedAccess ?: return
val calleeReference = callSite.calleeReference as? FirDiagnosticHolder ?: return
val diagnostic = calleeReference.diagnostic as? ConeInapplicableCandidateError ?: return
if (diagnostic.applicability != CandidateApplicability.INAPPLICABLE) return
candidate.addDiagnostic(InapplicableCandidate)
}
}
@@ -24,9 +24,9 @@ FILE: typeArgumentsNotAllowed.kt
}
}
public final val a: <ERROR TYPE REF: Unresolved name: MyClass> = Q|rest|.<Unresolved name: MyClass>#
public final val a: <ERROR TYPE REF: Unresolved name: MyClass> = Q|rest|.<Unresolved name: MyClass>#<R|kotlin/String|>
public get(): <ERROR TYPE REF: Unresolved name: MyClass>
public final val b: <ERROR TYPE REF: Unresolved name: MyClass> = Q|rest/Best|.<Unresolved name: MyClass>#
public final val b: <ERROR TYPE REF: Unresolved name: MyClass> = Q|rest/Best|.<Unresolved name: MyClass>#<R|kotlin/String|>
public get(): <ERROR TYPE REF: Unresolved name: MyClass>
public final class B<E> : R|kotlin/Any| {
public constructor<E>(): R|rest/B<E>| {
@@ -58,21 +58,21 @@ FILE: propertyAccessWithExplicitTypeArguments.kt
R|<local>/receiver|.R|/hello1|<R|kotlin/Int|>
R|<local>/receiver|.R|/hello1|<R|kotlin/Int|>.R|/invoke|<R|kotlin/Int|, R|kotlin/String|>()
R|<local>/receiver|.R|/hello1|<R|kotlin/Int|>
R|<local>/receiver|.R|/hello1|<R|kotlin/Int|>
R|<local>/receiver|.R|/hello1|<R|kotlin/Int|>
R|<local>/receiver|.R|/hello1|<R|kotlin/Int|, R|kotlin/String|>
R|<local>/receiver|.R|/hello1|<R|kotlin/Int|, R|kotlin/String|, R|kotlin/String|>
R|kotlin/with|<R|ContextImpl<kotlin/String>|, R|kotlin/String|>(R|/ContextImpl.ContextImpl|<R|kotlin/String|>(), <L> = with@fun R|ContextImpl<kotlin/String>|.<anonymous>(): R|kotlin/String| <inline=Inline, kind=EXACTLY_ONCE> {
R|/hello2|<R|kotlin/String|>
R|/hello2|<R|kotlin/String|>
R|/hello2|<R|kotlin/String|>.R|/invoke|<R|kotlin/String|, R|kotlin/Int|>()
R|/hello2|<R|kotlin/String|>
R|/hello2|<R|kotlin/String|>
R|/hello2|<R|kotlin/String|>
R|/hello2|<R|kotlin/String|, R|kotlin/Int|>
R|/hello2|<R|kotlin/String|, R|kotlin/Int|, R|kotlin/Int|>
R|<local>/receiver|.R|/hello3|<R|kotlin/Int|, R|kotlin/String|>
R|<local>/receiver|.R|/hello3|<R|kotlin/Int|, R|kotlin/String|>
R|<local>/receiver|.R|/hello3|<R|kotlin/Int|, R|kotlin/String|>.R|/invoke|<R|kotlin/Int|, R|kotlin/String|>()
R|<local>/receiver|.R|/hello3|<R|kotlin/Int|, R|kotlin/String|>
R|<local>/receiver|.R|/hello3|<R|kotlin/Int|, R|kotlin/String|>
^ R|<local>/receiver|.R|/hello3|<R|kotlin/Int|, R|kotlin/String|>
^ R|<local>/receiver|.R|/hello3|<R|kotlin/Int|, R|kotlin/String|, R|kotlin/String|>
}
)
}
@@ -14,8 +14,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors
import org.jetbrains.kotlin.fir.declarations.isJavaOrEnhancement
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.resolvedArgumentMapping
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
import org.jetbrains.kotlin.fir.originalOrSelf
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
import org.jetbrains.kotlin.types.model.typeConstructor
import kotlin.math.min
/**
* Checks compatibility of variance of type argument for Java collections.
@@ -53,7 +54,7 @@ object FirJavaGenericVarianceViolationTypeChecker : FirFunctionCallChecker() {
}
val argumentMapping = expression.resolvedArgumentMapping ?: return
val typeArgumentMap = mutableMapOf<FirTypeParameterSymbol, ConeKotlinType>()
for (i in 0 until expression.typeArguments.size) {
for (i in 0 until min(expression.typeArguments.size, calleeFunction.typeParameterSymbols.size)) {
val type = (expression.typeArguments[i] as? FirTypeProjectionWithVariance)?.typeRef?.coneType
if (type != null) {
typeArgumentMap[calleeFunction.typeParameterSymbols[i]] = type
@@ -43,6 +43,10 @@ class CandidateFactory private constructor(
constructor(context: ResolutionContext, callInfo: CallInfo) : this(context, buildBaseSystem(context, callInfo))
/**
* [createCandidate] doesn't make any guarantees for inapplicable calls. Errors in the call or callee do not necessarily result in an
* inapplicable [Candidate].
*/
fun createCandidate(
callInfo: CallInfo,
symbol: FirBasedSymbol<*>,
@@ -52,7 +52,10 @@ internal object MapTypeArguments : ResolutionStage() {
) {
candidate.typeArgumentMapping = TypeArgumentMapping.Mapped(typeArguments)
} else {
candidate.typeArgumentMapping = TypeArgumentMapping.Mapped(emptyList())
candidate.typeArgumentMapping = TypeArgumentMapping.Mapped(
if (typeArguments.size > owner.typeParameters.size) typeArguments.take(owner.typeParameters.size)
else typeArguments
)
sink.yieldDiagnostic(InapplicableCandidate)
}
}
@@ -513,7 +513,7 @@ class FirCallCompletionResultsWriterTransformer(
access: FirQualifiedAccess,
candidate: Candidate
): List<FirTypeProjection> {
return computeTypeArgumentTypes(candidate)
val typeArguments = computeTypeArgumentTypes(candidate)
.mapIndexed { index, type ->
when (val argument = access.typeArguments.getOrNull(index)) {
is FirTypeProjectionWithVariance -> {
@@ -540,6 +540,12 @@ class FirCallCompletionResultsWriterTransformer(
}
}
}
// We must ensure that all extra type arguments are preserved in the result, so that they can still be resolved later (e.g. for
// navigation in the IDE).
return if (typeArguments.size < access.typeArguments.size) {
typeArguments + access.typeArguments.subList(typeArguments.size, access.typeArguments.size)
} else typeArguments
}
private fun computeTypeArgumentTypes(
@@ -1,5 +1,6 @@
// IGNORE_ERRORS
// ERROR_POLICY: SEMANTIC
// IGNORE_BACKEND_K2: JS_IR
// MODULE: lib
// FILE: t.kt
@@ -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> */