diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt index cdfc0e31bb4..b09da067378 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt @@ -346,8 +346,9 @@ private fun Candidate.prepareExpectedType( context: ResolutionContext ): ConeKotlinType? { if (parameter == null) return null - if (parameter.returnTypeRef is FirILTTypeRefPlaceHolder && argument.resultType is FirResolvedTypeRef) - return argument.resultType.coneType + val parameterReturnTypeRef = parameter.returnTypeRef + if (parameterReturnTypeRef is FirILTTypeRefPlaceHolder && argument.resultType is FirResolvedTypeRef) + return argument.resultType.coneType.takeIf { it in parameterReturnTypeRef.type.possibleTypes } ?: session.builtinTypes.intType.type val basicExpectedType = argument.getExpectedType(session, parameter/*, LanguageVersionSettings*/) val expectedType = getExpectedTypeWithSAMConversion(session, argument, basicExpectedType, context) ?: basicExpectedType return this.substitutor.substituteOrSelf(expectedType) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/IntegerLiteralTypeApproximationTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/IntegerLiteralTypeApproximationTransformer.kt index 53bc4ee36c6..8bdac8a57c9 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/IntegerLiteralTypeApproximationTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/IntegerLiteralTypeApproximationTransformer.kt @@ -218,7 +218,9 @@ class IntegerOperatorsTypeUpdater(private val approximator: IntegerLiteralTypeAp } else -> { val expectedType = when (argumentType.classId) { - StandardClassIds.Long -> argumentType + StandardClassIds.Long, + StandardClassIds.Float, + StandardClassIds.Double -> argumentType else -> ConeIntegerLiteralTypeImpl.createType(StandardClassIds.Int) } functionCall.transformSingle(approximator, expectedType) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerLiteralTypeScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerLiteralTypeScope.kt index db30e5abc28..4a3adb85bfc 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerLiteralTypeScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerLiteralTypeScope.kt @@ -9,10 +9,7 @@ import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.contracts.impl.FirEmptyContractDescription -import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin -import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus -import org.jetbrains.kotlin.fir.declarations.FirResolvePhase -import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction +import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.impl.FirSimpleFunctionImpl @@ -42,6 +39,7 @@ class FirIntegerLiteralTypeScope(private val session: FirSession, val isUnsigned companion object { val BINARY_OPERATOR_NAMES = FirIntegerOperator.Kind.values().filterNot { it.unary }.map { it.operatorName } + val FLOATING_BINARY_OPERATOR_NAMES = FirIntegerOperator.Kind.values().filter { it.withFloatingRhs }.map { it.operatorName } val UNARY_OPERATOR_NAMES = FirIntegerOperator.Kind.values().filter { it.unary }.map { it.operatorName } private val ALL_OPERATORS = FirIntegerOperator.Kind.values().map { it.operatorName to it }.toMap() @@ -52,18 +50,16 @@ class FirIntegerLiteralTypeScope(private val session: FirSession, val isUnsigned private val BINARY_OPERATOR_SYMBOLS = BINARY_OPERATOR_NAMES.map { name -> name to FirNamedFunctionSymbol(CallableId(name)).apply { createFirFunction(name, this).apply { - val valueParameterName = Name.identifier("arg") - valueParameters += buildValueParameter { - source = null - origin = FirDeclarationOrigin.Synthetic - session = this@FirIntegerLiteralTypeScope.session - returnTypeRef = FirILTTypeRefPlaceHolder(isUnsigned) - this.name = valueParameterName - symbol = FirVariableSymbol(valueParameterName) - defaultValue = null - isCrossinline = false - isNoinline = false - isVararg = false + valueParameters += createValueParameter(FirILTTypeRefPlaceHolder(isUnsigned)) + } + } + }.toMap() + + private val FLOATING_BINARY_OPERATOR_SYMBOLS = FLOATING_BINARY_OPERATOR_NAMES.map { name -> + name to listOf(session.builtinTypes.floatType, session.builtinTypes.doubleType).map { typeRef -> + FirNamedFunctionSymbol(CallableId(name)).apply { + createFirFunction(name, this, typeRef).apply { + valueParameters += createValueParameter(typeRef) } } } @@ -75,10 +71,14 @@ class FirIntegerLiteralTypeScope(private val session: FirSession, val isUnsigned }.toMap() @OptIn(FirImplementationDetail::class) - private fun createFirFunction(name: Name, symbol: FirNamedFunctionSymbol): FirSimpleFunctionImpl = FirIntegerOperator( + private fun createFirFunction( + name: Name, + symbol: FirNamedFunctionSymbol, + returnTypeRef: FirResolvedTypeRef = FirILTTypeRefPlaceHolder(isUnsigned) + ): FirSimpleFunctionImpl = FirIntegerOperator( source = null, session, - FirILTTypeRefPlaceHolder(isUnsigned), + returnTypeRef, receiverTypeRef = null, ALL_OPERATORS.getValue(name), FirResolvedDeclarationStatusImpl(Visibilities.Public, Modality.FINAL), @@ -87,11 +87,29 @@ class FirIntegerLiteralTypeScope(private val session: FirSession, val isUnsigned resolvePhase = FirResolvePhase.BODY_RESOLVE } + private fun createValueParameter(returnTypeRef: FirResolvedTypeRef): FirValueParameter { + return buildValueParameter { + source = null + origin = FirDeclarationOrigin.Synthetic + session = this@FirIntegerLiteralTypeScope.session + this.returnTypeRef = returnTypeRef + name = Name.identifier("arg") + symbol = FirVariableSymbol(name) + defaultValue = null + isCrossinline = false + isNoinline = false + isVararg = false + } + } + override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) { - val symbol = BINARY_OPERATOR_SYMBOLS[name] - ?: UNARY_OPERATOR_SYMBOLS[name] - ?: return + UNARY_OPERATOR_SYMBOLS[name]?.let { + processor(it) + return + } + val symbol = BINARY_OPERATOR_SYMBOLS[name] ?: return processor(symbol) + FLOATING_BINARY_OPERATOR_SYMBOLS[name]?.forEach(processor) } override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { @@ -138,21 +156,21 @@ class FirIntegerOperator @FirImplementationDetail constructor( annotations = mutableListOf(), typeParameters = mutableListOf(), ) { - enum class Kind(val unary: Boolean, val operatorName: Name) { - PLUS(false, OperatorNameConventions.PLUS), - MINUS(false, OperatorNameConventions.MINUS), - TIMES(false, OperatorNameConventions.TIMES), - DIV(false, OperatorNameConventions.DIV), - REM(false, OperatorNameConventions.REM), - SHL(false, Name.identifier("shl")), - SHR(false, Name.identifier("shr")), - USHR(false, Name.identifier("ushr")), - XOR(false, Name.identifier("xor")), - AND(false, Name.identifier("and")), - OR(false, Name.identifier("or")), - UNARY_PLUS(true, OperatorNameConventions.UNARY_PLUS), - UNARY_MINUS(true, OperatorNameConventions.UNARY_MINUS), - INV(true, Name.identifier("inv")) + enum class Kind(val operatorName: Name, val unary: Boolean, val withFloatingRhs: Boolean) { + PLUS(OperatorNameConventions.PLUS, unary = false, withFloatingRhs = true), + MINUS(OperatorNameConventions.MINUS, unary = false, withFloatingRhs = true), + TIMES(OperatorNameConventions.TIMES, unary = false, withFloatingRhs = true), + DIV(OperatorNameConventions.DIV, unary = false, withFloatingRhs = true), + REM(OperatorNameConventions.REM, unary = false, withFloatingRhs = true), + SHL(Name.identifier("shl"), unary = false, withFloatingRhs = false), + SHR(Name.identifier("shr"), unary = false, withFloatingRhs = false), + USHR(Name.identifier("ushr"), unary = false, withFloatingRhs = false), + XOR(Name.identifier("xor"), unary = false, withFloatingRhs = false), + AND(Name.identifier("and"), unary = false, withFloatingRhs = false), + OR(Name.identifier("or"), unary = false, withFloatingRhs = false), + UNARY_PLUS(OperatorNameConventions.UNARY_PLUS, unary = true, withFloatingRhs = false), + UNARY_MINUS(OperatorNameConventions.UNARY_MINUS, unary = true, withFloatingRhs = false), + INV(Name.identifier("inv"), unary = true, withFloatingRhs = false), } } diff --git a/compiler/testData/codegen/box/strings/kt889.kt b/compiler/testData/codegen/box/strings/kt889.kt index 0e36b088b02..2736e0176e6 100644 --- a/compiler/testData/codegen/box/strings/kt889.kt +++ b/compiler/testData/codegen/box/strings/kt889.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_BACKEND: JS_IR // IGNORE_BACKEND: JS_IR_ES6 // TODO: muted automatically, investigate should it be ran for JS or not diff --git a/compiler/testData/diagnostics/tests/Basic.fir.kt b/compiler/testData/diagnostics/tests/Basic.fir.kt index 6da1912608e..8e482deb189 100644 --- a/compiler/testData/diagnostics/tests/Basic.fir.kt +++ b/compiler/testData/diagnostics/tests/Basic.fir.kt @@ -6,7 +6,7 @@ fun test() : Int { val a : () -> Unit = { foo(1) } - return 1 - "1" + return 1 - "1" } class A() { diff --git a/compiler/testData/diagnostics/tests/evaluate/logicWithNumber.fir.kt b/compiler/testData/diagnostics/tests/evaluate/logicWithNumber.fir.kt index 6c4ca0c41ef..42c4642839d 100644 --- a/compiler/testData/diagnostics/tests/evaluate/logicWithNumber.fir.kt +++ b/compiler/testData/diagnostics/tests/evaluate/logicWithNumber.fir.kt @@ -4,5 +4,5 @@ fun bar() { // See exception in KT-13421 fun foo() { - 42 and false -} \ No newline at end of file + 42 and false +} diff --git a/compiler/testData/diagnostics/tests/operatorRem/preferRemWithImplicitReceivers.fir.kt b/compiler/testData/diagnostics/tests/operatorRem/preferRemWithImplicitReceivers.fir.kt index 7778fdb28d5..e1a2d488c3e 100644 --- a/compiler/testData/diagnostics/tests/operatorRem/preferRemWithImplicitReceivers.fir.kt +++ b/compiler/testData/diagnostics/tests/operatorRem/preferRemWithImplicitReceivers.fir.kt @@ -12,9 +12,9 @@ class B { fun test() { with(B()) { with(A()) { - takeString(1 % "") + takeString(1 % "") } } } -fun takeString(s: String) {} \ No newline at end of file +fun takeString(s: String) {} diff --git a/compiler/tests-spec/testData/diagnostics/linked/overload-resolution/choosing-the-most-specific-candidate-from-the-overload-candidate-set/algorithm-of-msc-selection/p-12/pos/2.2.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/overload-resolution/choosing-the-most-specific-candidate-from-the-overload-candidate-set/algorithm-of-msc-selection/p-12/pos/2.2.fir.kt index d0160c36797..6b0541d5f9d 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/overload-resolution/choosing-the-most-specific-candidate-from-the-overload-candidate-set/algorithm-of-msc-selection/p-12/pos/2.2.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/overload-resolution/choosing-the-most-specific-candidate-from-the-overload-candidate-set/algorithm-of-msc-selection/p-12/pos/2.2.fir.kt @@ -84,8 +84,8 @@ class Case3 { } fun case() { - .plus; typeCall: function")!>1+"1" - 1+"1" + 1+"1" + 1+"1" } } @@ -95,15 +95,15 @@ fun case3(case: Case3) { //(1.1) return type is String case.boo+"1" - case.apply { .plus; typeCall: function")!>1+"1" } - case.apply { 1+"1" } + case.apply { 1+"1" } + case.apply { 1+"1" } - case.let { .plus; typeCall: function")!>1+"1" } - case.let { 1+"1" } + case.let { 1+"1" } + case.let { 1+"1" } - case.also { .plus; typeCall: function")!>1+"1" } - case.also { 1+"1" } + case.also { 1+"1" } + case.also { 1+"1" } - case.run { .plus; typeCall: function")!>1+"1" } - case.run { 1+"1" } + case.run { 1+"1" } + case.run { 1+"1" } }