diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeUtils.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeUtils.kt index c6c3182c4c3..3d0a5e17233 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeUtils.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeUtils.kt @@ -73,6 +73,9 @@ val ConeKotlinType.isArrayType: Boolean val ConeKotlinType.isNonPrimitiveArray: Boolean get() = this is ConeClassLikeType && lookupTag.classId == StandardClassIds.Array +val ConeKotlinType.isPrimitiveArray: Boolean + get() = this is ConeClassLikeType && lookupTag.classId in StandardClassIds.primitiveArrayTypeByElementType.values + private val builtinUnsignedTypes = setOf(StandardClassIds.UInt, StandardClassIds.UByte, StandardClassIds.ULong, StandardClassIds.UShort) val ConeKotlinType.isUnsignedTypeOrNullableUnsignedType: Boolean get() = isAnyOfBuiltinType(builtinUnsignedTypes) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt index 461f7696673..1cf9b8cf15c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt @@ -35,7 +35,6 @@ import org.jetbrains.kotlin.fir.types.builder.buildStarProjection import org.jetbrains.kotlin.fir.types.builder.buildTypeProjectionWithVariance import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl 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 @@ -44,7 +43,7 @@ class FirCallCompletionResultsWriterTransformer( override val session: FirSession, private val finalSubstitutor: ConeSubstitutor, private val typeCalculator: ReturnTypeCalculator, - private val typeApproximator: AbstractTypeApproximator, + private val typeApproximator: ConeTypeApproximator, private val dataFlowAnalyzer: FirDataFlowAnalyzer<*>, private val mode: Mode = Mode.Normal ) : FirAbstractTreeTransformer(phase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) { @@ -287,7 +286,7 @@ class FirCallCompletionResultsWriterTransformer( val substitutedType = finalSubstitutor.substituteOrNull(initialType) val finalType = typeApproximator.approximateToSuperType( type = substitutedType ?: initialType, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference, - ) as ConeKotlinType? ?: substitutedType + ) ?: substitutedType return withReplacedConeType(finalType) } @@ -475,7 +474,7 @@ class FirCallCompletionResultsWriterTransformer( finalSubstitutor.substituteOrSelf(it).let { substitutedType -> typeApproximator.approximateToSuperType( substitutedType, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference, - ) as ConeKotlinType? ?: substitutedType + ) ?: substitutedType } } } @@ -537,7 +536,8 @@ class FirCallCompletionResultsWriterTransformer( } if (needUpdateLambdaType) { - val resolvedTypeRef = anonymousFunction.constructFunctionalTypeRef(isSuspend = expectedType?.isSuspendFunctionType(session) == true) + val resolvedTypeRef = + anonymousFunction.constructFunctionalTypeRef(isSuspend = expectedType?.isSuspendFunctionType(session) == true) anonymousFunction.replaceTypeRef(resolvedTypeRef) session.lookupTracker?.recordTypeResolveAsLookup(resolvedTypeRef, anonymousFunction.source, null) } @@ -558,7 +558,8 @@ class FirCallCompletionResultsWriterTransformer( val newReturnTypeRef = resultFunction.returnTypeRef.withReplacedConeType(lastExpressionType) resultFunction.replaceReturnTypeRef(newReturnTypeRef) - val resolvedTypeRef = resultFunction.constructFunctionalTypeRef(isSuspend = expectedType?.isSuspendFunctionType(session) == true) + val resolvedTypeRef = + resultFunction.constructFunctionalTypeRef(isSuspend = expectedType?.isSuspendFunctionType(session) == true) resultFunction.replaceTypeRef(resolvedTypeRef) session.lookupTracker?.let { it.recordTypeResolveAsLookup(newReturnTypeRef, anonymousFunction.source, null) @@ -710,9 +711,14 @@ class FirCallCompletionResultsWriterTransformer( val expectedArrayType = data?.getExpectedType(arrayOfCall) val expectedArrayElementType = expectedArrayType?.arrayElementType() arrayOfCall.transformChildren(this, expectedArrayElementType?.toExpectedType()) - val arrayElementType = session.inferenceComponents.ctx.commonSuperTypeOrNull(arrayOfCall.arguments.map { it.typeRef.coneType }) - ?: session.builtinTypes.nullableAnyType.type - arrayOfCall.resultType = arrayOfCall.typeRef.resolvedTypeFromPrototype(arrayElementType.createArrayType()) + val arrayElementType = + session.inferenceComponents.ctx.commonSuperTypeOrNull(arrayOfCall.arguments.map { it.typeRef.coneType })?.let { + typeApproximator.approximateToSuperType(it, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference) + ?: it + } ?: expectedArrayElementType ?: session.builtinTypes.nullableAnyType.type + arrayOfCall.resultType = arrayOfCall.typeRef.resolvedTypeFromPrototype( + arrayElementType.createArrayType(createPrimitiveArrayType = expectedArrayType?.isPrimitiveArray == true) + ) return arrayOfCall } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt index aebb2cd17cd..7a172cde93f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt @@ -127,6 +127,22 @@ class FirSyntheticCallGenerator( return elvisExpression.transformCalleeReference(UpdateReference, reference) } + fun generateSyntheticCallForArrayOfCall(arrayOfCall: FirArrayOfCall, context: ResolutionContext): FirFunctionCall { + val argumentList = buildArgumentList { + arguments += arrayOfCall + } + return buildFunctionCall { + this.argumentList = argumentList + calleeReference = generateCalleeReferenceWithCandidate( + arrayOfCall, + idFunction, + argumentList, + SyntheticCallableId.ID.callableName, + context = context + ) + } + } + fun resolveCallableReferenceWithSyntheticOuterCall( callableReferenceAccess: FirCallableReferenceAccess, expectedTypeRef: FirTypeRef?, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt index 352276cb077..0993160d3a8 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt @@ -224,6 +224,10 @@ open class FirBodyResolveTransformer( return expressionsTransformer.transformCheckedSafeCallSubject(checkedSafeCallSubject, data) } + override fun transformArrayOfCall(arrayOfCall: FirArrayOfCall, data: ResolutionMode): FirStatement { + return expressionsTransformer.transformArrayOfCall(arrayOfCall, data) + } + // ------------------------------------- Declarations ------------------------------------- override fun transformDeclaration(declaration: FirDeclaration, data: ResolutionMode): FirDeclaration { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index f108f77c4e2..52937d08615 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -968,6 +968,17 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform return result } + override fun transformArrayOfCall(arrayOfCall: FirArrayOfCall, data: ResolutionMode): FirStatement { + if (data is ResolutionMode.ContextDependent) { + arrayOfCall.transformChildren(transformer, data) + return arrayOfCall + } + val syntheticIdCall = components.syntheticCallGenerator.generateSyntheticCallForArrayOfCall(arrayOfCall, resolutionContext) + arrayOfCall.transformChildren(transformer, ResolutionMode.ContextDependent) + callCompleter.completeCall(syntheticIdCall, data.expectedType ?: components.noExpectedType) + return arrayOfCall + } + // ------------------------------------------------------------------------------------------------ internal fun storeTypeFromCallee(access: T) where T : FirQualifiedAccess, T : FirExpression { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ArrayUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ArrayUtils.kt index adc92c06ae9..63cc5e2f792 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ArrayUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ArrayUtils.kt @@ -10,12 +10,12 @@ import org.jetbrains.kotlin.name.StandardClassIds val ConeKotlinType.isArrayOrPrimitiveArray: Boolean get() = arrayElementType() != null -fun ConeKotlinType.createOutArrayType(nullable: Boolean = false): ConeKotlinType { - return ConeKotlinTypeProjectionOut(this).createArrayType(nullable) +fun ConeKotlinType.createOutArrayType(nullable: Boolean = false, createPrimitiveArrayType: Boolean = true): ConeKotlinType { + return ConeKotlinTypeProjectionOut(this).createArrayType(nullable, createPrimitiveArrayType) } -fun ConeTypeProjection.createArrayType(nullable: Boolean = false): ConeClassLikeType { - if (this is ConeKotlinTypeProjection) { +fun ConeTypeProjection.createArrayType(nullable: Boolean = false, createPrimitiveArrayType: Boolean = true): ConeClassLikeType { + if (this is ConeKotlinTypeProjection && createPrimitiveArrayType) { val type = type.lowerBoundIfFlexible() if (type is ConeClassLikeType && type.nullability != ConeNullability.NULLABLE) { val classId = type.lookupTag.classId diff --git a/compiler/testData/diagnostics/tests/collectionLiterals/basicCollectionLiterals.fir.kt b/compiler/testData/diagnostics/tests/collectionLiterals/basicCollectionLiterals.fir.kt index b6236178bb0..c21f49ebfa5 100644 --- a/compiler/testData/diagnostics/tests/collectionLiterals/basicCollectionLiterals.fir.kt +++ b/compiler/testData/diagnostics/tests/collectionLiterals/basicCollectionLiterals.fir.kt @@ -7,18 +7,18 @@ fun test() { val b: Array = [] val c = [1, 2] val d: Array = [1, 2] - val e: Array = [1] + val e: Array = [1] val f: IntArray = [1, 2] val g = [f] } fun check() { - [1, 2] checkType { _>() } - [""] checkType { _>() } + [1, 2] checkType { _>() } + [""] checkType { _>() } val f: IntArray = [1] - [f] checkType { _>() } + [f] checkType { _>() } - [1, ""] checkType { _>() } + [1, ""] checkType { _>() } } diff --git a/compiler/testData/diagnostics/tests/collectionLiterals/collectionLiteralsAsPrimitiveArrays.fir.kt b/compiler/testData/diagnostics/tests/collectionLiterals/collectionLiteralsAsPrimitiveArrays.fir.kt index 99b93413995..94345de24f1 100644 --- a/compiler/testData/diagnostics/tests/collectionLiterals/collectionLiteralsAsPrimitiveArrays.fir.kt +++ b/compiler/testData/diagnostics/tests/collectionLiterals/collectionLiteralsAsPrimitiveArrays.fir.kt @@ -12,7 +12,7 @@ fun basicTypes() { } fun basicTypesWithErrors() { - val a: IntArray = [1.0] - val b: ShortArray = [1.0] - val c: CharArray = ["a"] -} \ No newline at end of file + val a: IntArray = [1.0] + val b: ShortArray = [1.0] + val c: CharArray = ["a"] +} diff --git a/compiler/testData/diagnostics/tests/collectionLiterals/collectionLiteralsOutsideOfAnnotations.fir.kt b/compiler/testData/diagnostics/tests/collectionLiterals/collectionLiteralsOutsideOfAnnotations.fir.kt index 215c070f604..f6cf7cb82d8 100644 --- a/compiler/testData/diagnostics/tests/collectionLiterals/collectionLiteralsOutsideOfAnnotations.fir.kt +++ b/compiler/testData/diagnostics/tests/collectionLiterals/collectionLiteralsOutsideOfAnnotations.fir.kt @@ -10,7 +10,7 @@ fun test() { takeArray([""]) val v = [""] [""] - [1, 2, 3].size + [1, 2, 3].size } fun baz(arg: Array = []) { diff --git a/compiler/testData/diagnostics/tests/collectionLiterals/noCollectionLiterals.fir.kt b/compiler/testData/diagnostics/tests/collectionLiterals/noCollectionLiterals.fir.kt index 6525f070c28..bad970ee226 100644 --- a/compiler/testData/diagnostics/tests/collectionLiterals/noCollectionLiterals.fir.kt +++ b/compiler/testData/diagnostics/tests/collectionLiterals/noCollectionLiterals.fir.kt @@ -1,12 +1,12 @@ // !WITH_NEW_INFERENCE fun test(): Array { [1, 2] - [1, 2][0] - [1, 2].get(0) + [1, 2][0] + [1, 2].get(0) foo([""]) - val p = [1, 2] + [3, 4] + val p = [1, 2] + [3, 4] return [1, 2] }