FIR: Use Any? expect type to the argument list of ==

^KT-47409 Related
This commit is contained in:
Denis.Zharkov
2021-06-23 15:19:35 +03:00
committed by TeamCityServer
parent 4892ad42b9
commit c8c558b575
9 changed files with 64 additions and 17 deletions
@@ -2421,6 +2421,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
runTest("compiler/fir/analysis-tests/testData/resolve/inference/elvisAndUnit.kt");
}
@TestMetadata("equals.kt")
public void testEquals() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/inference/equals.kt");
}
@TestMetadata("extensionCallableReferences.kt")
public void testExtensionCallableReferences() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/inference/extensionCallableReferences.kt");
@@ -0,0 +1,18 @@
FILE: equals.kt
public final fun <T> materialize(): R|T| {
^materialize R|kotlin/TODO|()
}
public final fun main(): R|kotlin/Unit| {
when () {
==(String(), R|/materialize|<R|kotlin/Any?|>()) -> {
^main Unit
}
}
when () {
==(R|/materialize|<R|kotlin/Any?|>(), String()) -> {
^main Unit
}
}
}
@@ -0,0 +1,6 @@
fun <T> materialize(): T = TODO()
fun main() {
if ("" == materialize()) return // FE1.0: OK, type argument inferred to Any?
if (materialize() == "") return // FE1.0: Error, uninferred type argument for `T`
}
@@ -2751,6 +2751,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
runTest("compiler/fir/analysis-tests/testData/resolve/inference/elvisAndUnit.kt");
}
@Test
@TestMetadata("equals.kt")
public void testEquals() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/inference/equals.kt");
}
@Test
@TestMetadata("extensionCallableReferences.kt")
public void testExtensionCallableReferences() throws Exception {
@@ -2751,6 +2751,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolve/inference/elvisAndUnit.kt");
}
@Test
@TestMetadata("equals.kt")
public void testEquals() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/inference/equals.kt");
}
@Test
@TestMetadata("extensionCallableReferences.kt")
public void testExtensionCallableReferences() throws Exception {
@@ -26,12 +26,16 @@ import org.jetbrains.kotlin.fir.resolve.diagnostics.*
import org.jetbrains.kotlin.fir.resolve.inference.FirStubInferenceSession
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.transformers.*
import org.jetbrains.kotlin.fir.resolve.transformers.InvocationKindTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.StoreReceiver
import org.jetbrains.kotlin.fir.resolve.transformers.firClassLike
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.visitors.*
import org.jetbrains.kotlin.fir.visitors.FirDefaultTransformer
import org.jetbrains.kotlin.fir.visitors.TransformData
import org.jetbrains.kotlin.fir.visitors.transformSingle
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.resolve.calls.inference.buildAbstractResultingSubstitutor
@@ -490,10 +494,16 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
equalityOperatorCall: FirEqualityOperatorCall,
data: ResolutionMode
): FirStatement {
val result = (equalityOperatorCall.transformChildren(transformer, ResolutionMode.ContextIndependent) as FirEqualityOperatorCall)
.also { it.resultType = equalityOperatorCall.typeRef.resolvedTypeFromPrototype(builtinTypes.booleanType.type) }
dataFlowAnalyzer.exitEqualityOperatorCall(result)
return result
// Currently, we use expectedType=Any? for both operands
// In FE1.0, it's only used for the right
// But it seems a bit inconsistent (see KT-47409)
// Also it's kind of complicated to transform different arguments with different expectType considering current FIR structure
equalityOperatorCall.transformAnnotations(transformer, ResolutionMode.ContextIndependent)
equalityOperatorCall.argumentList.transformArguments(transformer, withExpectedType(builtinTypes.nullableAnyType))
equalityOperatorCall.resultType = equalityOperatorCall.typeRef.resolvedTypeFromPrototype(builtinTypes.booleanType.type)
dataFlowAnalyzer.exitEqualityOperatorCall(equalityOperatorCall)
return equalityOperatorCall
}
private inline fun <T> resolveCandidateForAssignmentOperatorCall(block: () -> T): T {
@@ -1,11 +0,0 @@
// !LANGUAGE: +NewInference
interface Base
fun <K> materialize(): K = TODO()
fun <T : Base> Base.transform(): T = materialize()
fun test(child: Base) {
child == child.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>transform<!>()
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !LANGUAGE: +NewInference
interface Base
@@ -2751,6 +2751,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis
runTest("compiler/fir/analysis-tests/testData/resolve/inference/elvisAndUnit.kt");
}
@Test
@TestMetadata("equals.kt")
public void testEquals() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/inference/equals.kt");
}
@Test
@TestMetadata("extensionCallableReferences.kt")
public void testExtensionCallableReferences() throws Exception {