diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt index f25c351a94f..9774f8bf881 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt @@ -28,11 +28,8 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirScriptSymbol -import org.jetbrains.kotlin.fir.types.ConeErrorType -import org.jetbrains.kotlin.fir.types.ConeKotlinType +import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef -import org.jetbrains.kotlin.fir.types.coneTypeSafe -import org.jetbrains.kotlin.fir.types.constructType import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.SmartcastStability @@ -51,9 +48,7 @@ abstract class ReceiverValue { class ExpressionReceiverValue(override val receiverExpression: FirExpression) : ReceiverValue() { override val type: ConeKotlinType - // NB: safe cast is necessary here - get() = receiverExpression.coneTypeSafe() - ?: ConeErrorType(ConeIntermediateDiagnostic("No type calculated for: ${receiverExpression.renderWithType()}")) // TODO: assert here + get() = receiverExpression.resolvedType override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirTypeScope? { var receiverExpr: FirExpression? = receiverExpression diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt index 50cf4aac569..94c4f752604 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt @@ -549,7 +549,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty } val customAnnotations = attributes.customAnnotations return customAnnotations.any { - it.coneTypeSafe()?.fullyExpandedType(session)?.classId?.asSingleFqName() == fqName + it.resolvedType.fullyExpandedType(session).classId?.asSingleFqName() == fqName } } @@ -558,7 +558,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty // We don't check for compiler attributes because all of them doesn't have parameters val customAnnotations = attributes.customAnnotations val annotationCall = customAnnotations.firstOrNull { - it.coneTypeSafe()?.fullyExpandedType(session)?.classId?.asSingleFqName() == fqName + it.resolvedType.fullyExpandedType(session).classId?.asSingleFqName() == fqName } ?: return null val argument = when (val argument = annotationCall.argumentMapping.mapping.values.firstOrNull() ?: return null) { is FirVarargArgumentsExpression -> argument.arguments.firstOrNull() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt index e11e718e9d2..7e698125f41 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -826,7 +826,7 @@ class FirCallResolver( */ if (components.context.inferenceSession !is FirBuilderInferenceSession && createResolvedReferenceWithoutCandidateForLocalVariables && - explicitReceiver?.coneTypeSafe() == null && + explicitReceiver?.resolvedType !is ConeIntegerLiteralType && coneSymbol is FirVariableSymbol && (coneSymbol !is FirPropertySymbol || (coneSymbol.fir as FirMemberDeclaration).typeParameters.isEmpty()) && !candidate.doesResolutionResultOverrideOtherToPreserveCompatibility() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt index c260091edf4..954f2b45f8d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt @@ -64,7 +64,7 @@ fun FirAnonymousFunction.addReturnToLastStatementIfNeeded(session: FirSession) { val lastStatement = body.statements.lastOrNull() as? FirExpression ?: return if (lastStatement is FirReturnExpression) return - val returnType = body.coneTypeOrNull ?: return + val returnType = body.resolvedType if (returnType.isNothing) return val returnTarget = FirFunctionTarget(null, isLambda = isLambda).also { it.bind(this) } @@ -211,7 +211,7 @@ fun BodyResolveComponents.buildResolvedQualifierForClass( this.annotations.addAll(annotations) }.build().apply { if (classId.isLocal) { - resultType = typeForQualifierByDeclaration(regularClass.fir, resultType, session) + resultType = typeForQualifierByDeclaration(regularClass.fir, session) ?.also { replaceCanBeValue(true) } ?: session.builtinTypes.unitType.type } else { @@ -222,12 +222,11 @@ fun BodyResolveComponents.buildResolvedQualifierForClass( fun FirResolvedQualifier.setTypeOfQualifier(session: FirSession) { val classSymbol = symbol - val resultType = resultType if (classSymbol != null) { classSymbol.lazyResolveToPhase(FirResolvePhase.TYPES) val declaration = classSymbol.fir if (declaration !is FirTypeAlias || typeArguments.isEmpty()) { - val typeByDeclaration = typeForQualifierByDeclaration(declaration, resultType, session) + val typeByDeclaration = typeForQualifierByDeclaration(declaration, session) if (typeByDeclaration != null) { this.resultType = typeByDeclaration replaceCanBeValue(true) @@ -243,10 +242,10 @@ internal fun typeForReifiedParameterReference(parameterReferenceBuilder: FirReso return typeParameterSymbol.constructType(emptyArray(), false) } -internal fun typeForQualifierByDeclaration(declaration: FirDeclaration, resultType: ConeKotlinType?, session: FirSession): ConeKotlinType? { +internal fun typeForQualifierByDeclaration(declaration: FirDeclaration, session: FirSession): ConeKotlinType? { if (declaration is FirTypeAlias) { val expandedDeclaration = declaration.expandedConeType?.lookupTag?.toSymbol(session)?.fir ?: return null - return typeForQualifierByDeclaration(expandedDeclaration, resultType, session) + return typeForQualifierByDeclaration(expandedDeclaration, session) } if (declaration is FirRegularClass) { if (declaration.classKind == ClassKind.OBJECT) { @@ -398,7 +397,7 @@ private fun FirSmartCastExpressionBuilder.applyResultTypeRef() { if (smartcastStability == SmartcastStability.STABLE_VALUE) smartcastType.coneTypeOrNull else - originalExpression.coneTypeOrNull + originalExpression.resolvedType } private fun BodyResolveComponents.transformExpressionUsingSmartcastInfo( @@ -473,8 +472,7 @@ fun FirCheckedSafeCallSubject.propagateTypeFromOriginalReceiver( ?.takeIf { it.isStable } ?.smartcastTypeWithoutNullableNothing ?.coneTypeSafe() - ?: nullableReceiverExpression.coneTypeOrNull - ?: return + ?: nullableReceiverExpression.resolvedType val expandedReceiverType = receiverType.fullyExpandedType(session) val updatedReceiverType = expandedReceiverType.makeConeTypeDefinitelyNotNullOrNotNull(session.typeContext).independentInstance() @@ -490,7 +488,7 @@ fun FirSafeCallExpression.propagateTypeFromQualifiedAccessAfterNullCheck( val resultingType = when { selector is FirExpression && !selector.isStatementLikeExpression -> { - val type = selector.coneTypeSafe() ?: return + val type = selector.resolvedType type.withNullability(ConeNullability.NULLABLE, session.typeContext) } // Branch for things that shouldn't be used as expressions. 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 ff52cf2f6b8..4848c6d0bfd 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 @@ -222,7 +222,7 @@ fun Candidate.resolvePlainExpressionArgument( ) { if (expectedType == null) return - val argumentType = argument.coneTypeSafe() ?: return + val argumentType = argument.resolvedType resolvePlainArgumentType( csBuilder, argument, @@ -434,7 +434,9 @@ internal fun Candidate.resolveArgument( sink: CheckerSink, context: ResolutionContext ) { - argument.resultType.ensureResolvedTypeDeclaration(context.session) + // Lambdas and callable references can be unresolved at this point + @OptIn(UnresolvedExpressionTypeAccess::class) + argument.coneTypeOrNull.ensureResolvedTypeDeclaration(context.session) val expectedType = prepareExpectedType(context.session, context.bodyResolveComponents.scopeSession, callInfo, argument, parameter, context) resolveArgumentExpression( @@ -533,7 +535,7 @@ fun FirExpression.isFunctional( is FirAnonymousFunctionExpression, is FirCallableReferenceAccess -> return true else -> { // Either a functional type or a subtype of a class that has a contributed `invoke`. - val coneType = coneTypeSafe() ?: return false + val coneType = resolvedType if (coneType.isSomeFunctionType(session)) { return true } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallableReferenceResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallableReferenceResolution.kt index 8a0e88a2f67..353bb01926b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallableReferenceResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallableReferenceResolution.kt @@ -12,10 +12,7 @@ import org.jetbrains.kotlin.builtins.functions.isBasicFunctionOrKFunction import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.expressions.FirAnnotation -import org.jetbrains.kotlin.fir.expressions.FirExpression -import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression -import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier +import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.builder.buildNamedArgumentExpression import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnsupportedCallableReferenceTarget @@ -409,6 +406,7 @@ class FirFakeArgumentForCallableReference( override val source: KtSourceElement? get() = null + @UnresolvedExpressionTypeAccess override val coneTypeOrNull: ConeKotlinType get() = shouldNotBeCalled() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt index 519dfbc7add..00fea07efbc 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt @@ -62,7 +62,7 @@ internal object CheckExplicitReceiverConsistency : ResolutionStage() { when (receiverKind) { NO_EXPLICIT_RECEIVER -> { if (explicitReceiver != null && explicitReceiver !is FirResolvedQualifier && !explicitReceiver.isSuperReferenceExpression()) { - return sink.yieldDiagnostic(InapplicableWrongReceiver(actualType = explicitReceiver.coneTypeSafe())) + return sink.yieldDiagnostic(InapplicableWrongReceiver(actualType = explicitReceiver.resolvedType)) } } EXTENSION_RECEIVER, DISPATCH_RECEIVER -> { @@ -742,7 +742,7 @@ internal object LowerPriorityIfDynamic : ResolutionStage() { when { candidate.symbol.origin is FirDeclarationOrigin.DynamicScope -> candidate.addDiagnostic(LowerPriorityForDynamic) - candidate.callInfo.isImplicitInvoke && candidate.callInfo.explicitReceiver?.coneTypeSafe() != null -> + candidate.callInfo.isImplicitInvoke && candidate.callInfo.explicitReceiver?.resolvedType is ConeDynamicType -> candidate.addDiagnostic(LowerPriorityForDynamic) } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt index 3a691a939ab..a4d092ea6f6 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt @@ -923,7 +923,7 @@ abstract class FirDataFlowAnalyzer( } fun exitConstExpression(constExpression: FirConstExpression<*>) { - if (constExpression.coneTypeOrNull != null) return + if (constExpression.isResolved) return graphBuilder.exitConstExpression(constExpression).mergeIncomingFlow() } @@ -1135,7 +1135,6 @@ abstract class FirDataFlowAnalyzer( } } - @OptIn(UnexpandedTypeCheck::class) fun exitElvis(elvisExpression: FirElvisExpression, isLhsNotNull: Boolean, callCompleted: Boolean) { val node = graphBuilder.exitElvis(isLhsNotNull, callCompleted) node.mergeIncomingFlow { path, flow -> @@ -1146,7 +1145,8 @@ abstract class FirDataFlowAnalyzer( val elvisVariable by lazy { variableStorage.createSynthetic(elvisExpression) } // If (x ?: null) != null then x != null - if (elvisExpression.rhs.resultType?.isNullableNothing == true) { + @OptIn(UnresolvedExpressionTypeAccess::class) // Lambdas can have unresolved type here, see KT-61837 + if (elvisExpression.rhs.coneTypeOrNull?.isNullableNothing == true) { val lhsVariable = variableStorage.getOrCreateIfReal(flow, elvisExpression.lhs) if (lhsVariable != null) { flow.addImplication((elvisVariable notEq null) implies (lhsVariable notEq null)) @@ -1154,7 +1154,8 @@ abstract class FirDataFlowAnalyzer( } // If (null ?: x) != null then x != null - if (elvisExpression.lhs.resultType?.isNullableNothing == true) { + @OptIn(UnresolvedExpressionTypeAccess::class) // Lambdas can have unresolved type here, see KT-61837 + if (elvisExpression.lhs.coneTypeOrNull?.isNullableNothing == true) { val rhsVariable = variableStorage.getOrCreateIfReal(flow, elvisExpression.rhs) if (rhsVariable != null) { flow.addImplication((elvisVariable notEq null) implies (rhsVariable notEq null)) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt index 74a49281b7d..f7553801678 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt @@ -17,7 +17,6 @@ import org.jetbrains.kotlin.fir.expressions.builder.buildUnitExpression import org.jetbrains.kotlin.fir.references.toResolvedConstructorSymbol import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.resolve.dfa.* -import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.fir.types.* @@ -1115,7 +1114,7 @@ class ControlFlowGraphBuilder { // KT-59726 // @returns `true` if node actually returned Nothing private fun completeFunctionCall(node: FunctionCallNode): Boolean { - if (node.fir.resultType?.isNothing != true) return false + if (!node.fir.hasNothingType) return false val stub = StubNode(node.owner, node.level) val edges = node.followingNodes.map { it to node.edgeTo(it) } CFGNode.removeAllOutgoingEdges(node) @@ -1132,7 +1131,7 @@ class ControlFlowGraphBuilder { // ----------------------------------- Resolvable call ----------------------------------- fun exitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression): QualifiedAccessNode { - val returnsNothing = qualifiedAccessExpression.resultType?.isNothing == true + val returnsNothing = qualifiedAccessExpression.hasNothingType val node = createQualifiedAccessNode(qualifiedAccessExpression) if (returnsNothing) { addNonSuccessfullyTerminatingNode(node) @@ -1143,7 +1142,7 @@ class ControlFlowGraphBuilder { } fun exitSmartCastExpression(smartCastExpression: FirSmartCastExpression): SmartCastExpressionExitNode { - val returnsNothing = smartCastExpression.resultType?.isNothing == true + val returnsNothing = smartCastExpression.hasNothingType val node = createSmartCastExitNode(smartCastExpression) if (returnsNothing) { addNonSuccessfullyTerminatingNode(node) @@ -1176,7 +1175,7 @@ class ControlFlowGraphBuilder { } fun exitFunctionCall(functionCall: FirFunctionCall, callCompleted: Boolean): FunctionCallNode { - val returnsNothing = functionCall.resultType?.isNothing == true + val returnsNothing = functionCall.hasNothingType val node = createFunctionCallNode(functionCall) unifyDataFlowFromPostponedLambdas(node, callCompleted) if (returnsNothing) { @@ -1241,7 +1240,7 @@ class ControlFlowGraphBuilder { fun exitCheckNotNullCall(checkNotNullCall: FirCheckNotNullCall, callCompleted: Boolean): CheckNotNullCallNode { val node = createCheckNotNullCallNode(checkNotNullCall) unifyDataFlowFromPostponedLambdas(node, callCompleted) - if (checkNotNullCall.resultType?.isNothing == true) { + if (checkNotNullCall.hasNothingType) { addNonSuccessfullyTerminatingNode(node) } else { addNewSimpleNode(node) @@ -1348,7 +1347,9 @@ class ControlFlowGraphBuilder { } val lhsIsNotNullNode = createElvisLhsIsNotNullNode(elvisExpression).also { - val lhsIsNull = elvisExpression.lhs.coneTypeSafe()?.isNullableNothing == true + // TODO Refactor annotation arguments phase to not build CFG so that we can use resolvedType instead, see KT-61834 + @OptIn(UnresolvedExpressionTypeAccess::class) + val lhsIsNull = elvisExpression.lhs.coneTypeOrNull?.isNullableNothing == true addEdge(lhsExitNode, it, isDead = lhsIsNull) addEdge(it, exitNode, propagateDeadness = false) } @@ -1465,3 +1466,8 @@ val FirControlFlowGraphOwner.isUsedInControlFlowGraphBuilderForFile: Boolean is FirProperty -> memberShouldHaveGraph else -> false } + +// TODO Refactor annotation arguments phase to not build CFG so that we can use resolvedType instead, see KT-61834 +@OptIn(UnresolvedExpressionTypeAccess::class) +private val FirExpression.hasNothingType: Boolean + get() = coneTypeOrNull?.isNothing == true diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt index 818065189d8..2b4a6d7ff9b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt @@ -263,6 +263,8 @@ class FirStubTypeTransformer(private val substitutor: ConeSubstitutor) : FirDefa // FirAnonymousFunctionExpression doesn't support replacing the type // since it delegates the getter to the underlying FirAnonymousFunction. if (element is FirExpression && element !is FirAnonymousFunctionExpression) { + // TODO Check why some expressions have unresolved type in builder inference session KT-61835 + @OptIn(UnresolvedExpressionTypeAccess::class) element.coneTypeOrNull ?.let(substitutor::substituteOrNull) ?.let { element.replaceConeTypeOrNull(it) } @@ -273,7 +275,7 @@ class FirStubTypeTransformer(private val substitutor: ConeSubstitutor) : FirDefa } override fun transformTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall, data: Nothing?): FirStatement { - if (typeOperatorCall.argument.coneTypeOrNull is ConeStubType) { + if (typeOperatorCall.argument.resolvedType is ConeStubType) { typeOperatorCall.replaceArgFromStubType(true) } return super.transformTypeOperatorCall(typeOperatorCall, data) 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 1e2c30d76ef..1b711fca5ed 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 @@ -265,7 +265,7 @@ class FirCallCompletionResultsWriterTransformer( val result = prepareQualifiedTransform(qualifiedAccessExpression, calleeReference) val subCandidate = calleeReference.candidate - val resultType = result.coneTypeOrNull?.substituteType(subCandidate) + val resultType = result.resolvedType.substituteType(subCandidate) resultType.ensureResolvedTypeDeclaration(session) result.replaceConeTypeOrNull(resultType) session.lookupTracker?.recordTypeResolveAsLookup(resultType, qualifiedAccessExpression.source, context.file.source) @@ -726,18 +726,16 @@ class FirCallCompletionResultsWriterTransformer( } override fun transformBlock(block: FirBlock, data: ExpectedArgumentType?): FirStatement { - val initialType = block.coneTypeSafe() - if (initialType != null) { - var resultType = finallySubstituteOrNull(initialType) ?: block.resultType - (resultType as? ConeIntegerLiteralType)?.let { - resultType = - it.getApproximatedType(data?.getExpectedType(block)?.fullyExpandedType(session)) - } - block.replaceConeTypeOrNull(resultType) - session.lookupTracker?.recordTypeResolveAsLookup(resultType, block.source, context.file.source) + val initialType = block.resolvedType + var resultType = finallySubstituteOrNull(initialType) ?: block.resolvedType + (resultType as? ConeIntegerLiteralType)?.let { + resultType = + it.getApproximatedType(data?.getExpectedType(block)?.fullyExpandedType(session)) } + block.replaceConeTypeOrNull(resultType) + session.lookupTracker?.recordTypeResolveAsLookup(resultType, block.source, context.file.source) transformElement(block, data) - if (block.resultType is ConeErrorType) { + if (block.resolvedType is ConeErrorType) { block.writeResultType(session) } return block @@ -838,7 +836,7 @@ class FirCallCompletionResultsWriterTransformer( } override fun transformArrayLiteral(arrayLiteral: FirArrayLiteral, data: ExpectedArgumentType?): FirStatement { - if (arrayLiteral.coneTypeOrNull != null) return arrayLiteral + if (arrayLiteral.isResolved) return arrayLiteral val expectedArrayType = data?.getExpectedType(arrayLiteral) val expectedArrayElementType = expectedArrayType?.arrayElementType() arrayLiteral.transformChildren(this, expectedArrayElementType?.toExpectedType()) 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 c386d55bc31..a7a2e543cd0 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 @@ -242,7 +242,7 @@ class FirSyntheticCallGenerator( // If the callable reference cannot be resolved with the expected type, let's try to resolve it with any type and report // something like INITIALIZER_TYPE_MISMATCH or NONE_APPLICABLE instead of UNRESOLVED_REFERENCE. - check(callableReferenceAccess.calleeReference is FirSimpleNamedReference && callableReferenceAccess.coneTypeOrNull == null) { + check(callableReferenceAccess.calleeReference is FirSimpleNamedReference && !callableReferenceAccess.isResolved) { "Expected FirCallableReferenceAccess to be unresolved." } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt index 13624899c99..54abf86f4f6 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt @@ -223,7 +223,7 @@ private object WhenOnNullableExhaustivenessChecker : WhenExhaustivenessChecker() private object ConditionChecker : AbstractConditionChecker() { override fun visitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall, data: Flags) { val argument = equalityOperatorCall.arguments[1] - if (argument.coneTypeOrNull?.isNullableNothing == true) { + if (argument.resolvedType.isNullableNothing) { data.containsNull = true } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/IntegerLiteralAndOperatorApproximationTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/IntegerLiteralAndOperatorApproximationTransformer.kt index 1ca4b69c3ad..58f271aee75 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/IntegerLiteralAndOperatorApproximationTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/IntegerLiteralAndOperatorApproximationTransformer.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.expressions.FirConstExpression import org.jetbrains.kotlin.fir.expressions.FirIntegerLiteralOperatorCall import org.jetbrains.kotlin.fir.expressions.FirStatement +import org.jetbrains.kotlin.fir.expressions.UnresolvedExpressionTypeAccess import org.jetbrains.kotlin.fir.expressions.builder.buildFunctionCall import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference @@ -59,8 +60,9 @@ class IntegerLiteralAndOperatorApproximationTransformer( override fun transformConstExpression( constExpression: FirConstExpression, - data: ConeKotlinType? + data: ConeKotlinType?, ): FirStatement { + @OptIn(UnresolvedExpressionTypeAccess::class) val type = constExpression.coneTypeSafe() ?: return constExpression val approximatedType = type.getApproximatedType(data?.fullyExpandedType(session)) constExpression.resultType = approximatedType @@ -72,10 +74,12 @@ class IntegerLiteralAndOperatorApproximationTransformer( override fun transformIntegerLiteralOperatorCall( integerLiteralOperatorCall: FirIntegerLiteralOperatorCall, - data: ConeKotlinType? + data: ConeKotlinType?, ): FirStatement { @Suppress("UnnecessaryVariable") val call = integerLiteralOperatorCall + + @OptIn(UnresolvedExpressionTypeAccess::class) val operatorType = call.coneTypeSafe() ?: return call val approximatedType = operatorType.getApproximatedType(data?.fullyExpandedType(session)) call.transformDispatchReceiver(this, null) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt index 89e29101dd4..0c66cc9c4d7 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.expressions.FirBlock import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression +import org.jetbrains.kotlin.fir.expressions.UnresolvedExpressionTypeAccess import org.jetbrains.kotlin.fir.expressions.builder.buildVarargArgumentsExpression import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider import org.jetbrains.kotlin.fir.types.* @@ -22,8 +23,9 @@ import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.types.ConstantValueKind -internal inline var FirExpression.resultType: ConeKotlinType? - get() = coneTypeOrNull + +internal inline var FirExpression.resultType: ConeKotlinType + get() = resolvedType set(type) { replaceConeTypeOrNull(type) } @@ -87,11 +89,10 @@ fun FirBlock.writeResultType(session: FirSession) { is FirExpression -> statement else -> null } - resultType = if (resultExpression == null) { - session.builtinTypes.unitType.type - } else { - resultExpression.resultType ?: ConeErrorType(ConeSimpleDiagnostic("No type for block", DiagnosticKind.InferenceError)) - } + + // If a lambda contains another lambda as result expression, it won't be resolved at this point + @OptIn(UnresolvedExpressionTypeAccess::class) + resultType = resultExpression?.coneTypeOrNull ?: session.builtinTypes.unitType.type } fun ConstantValueKind<*>.expectedConeType(session: FirSession): ConeKotlinType { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirArrayOfCallTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirArrayOfCallTransformer.kt index 69135c3a38d..790e1c9fff8 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirArrayOfCallTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirArrayOfCallTransformer.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.coneTypeSafe import org.jetbrains.kotlin.fir.types.isArrayType +import org.jetbrains.kotlin.fir.types.resolvedType import org.jetbrains.kotlin.fir.visitors.FirDefaultTransformer /** @@ -45,7 +46,7 @@ class FirArrayOfCallTransformer : FirDefaultTransformer() { } } } - coneTypeOrNull = functionCall.coneTypeOrNull + coneTypeOrNull = functionCall.resolvedType } val calleeReference = functionCall.calleeReference diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt index 988d555dc50..5354524ad63 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt @@ -56,7 +56,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes // ------------------------------- When expressions ------------------------------- override fun transformWhenExpression(whenExpression: FirWhenExpression, data: ResolutionMode): FirStatement { - if (whenExpression.calleeReference is FirResolvedNamedReference && whenExpression.resultType != null) { + if (whenExpression.calleeReference is FirResolvedNamedReference && whenExpression.isResolved) { return whenExpression } whenExpression.annotations.forEach { it.accept(this, data) } @@ -71,7 +71,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes whenExpression.branches.isEmpty() -> {} whenExpression.isOneBranch() && data.forceFullCompletion && data !is ResolutionMode.WithExpectedType -> { whenExpression = whenExpression.transformBranches(transformer, ResolutionMode.ContextIndependent) - whenExpression.resultType = whenExpression.branches.first().result.resultType + whenExpression.resultType = whenExpression.branches.first().result.resolvedType // when with one branch cannot be completed if it's not already complete in the first place } else -> { @@ -143,7 +143,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes data: ResolutionMode ): FirStatement { val parentWhen = whenSubjectExpression.whenRef.value - val subjectType = parentWhen.subject?.resultType ?: parentWhen.subjectVariable?.returnTypeRef?.coneTypeOrNull + val subjectType = parentWhen.subject?.resolvedType ?: parentWhen.subjectVariable?.returnTypeRef?.coneTypeOrNull if (subjectType != null) { whenSubjectExpression.resultType = subjectType } @@ -154,7 +154,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes // ------------------------------- Try/catch expressions ------------------------------- override fun transformTryExpression(tryExpression: FirTryExpression, data: ResolutionMode): FirStatement { - if (tryExpression.calleeReference is FirResolvedNamedReference && tryExpression.resultType != null) { + if (tryExpression.calleeReference is FirResolvedNamedReference && tryExpression.isResolved) { return tryExpression } @@ -262,22 +262,21 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes ) var isLhsNotNull = false - if (result.rhs.coneTypeSafe()?.isNothing == true) { - val lhsType = result.lhs.coneTypeSafe() - if (lhsType != null) { - // Converting to non-raw type is necessary to preserver the K1 semantics (see KT-54526) - val newReturnType = - lhsType.makeConeTypeDefinitelyNotNullOrNotNull(session.typeContext) - .convertToNonRawVersion() - result.replaceConeTypeOrNull(newReturnType) - isLhsNotNull = true - } + + // TODO Check if the type of the RHS being null can lead to a bug, see KT-61837 + @OptIn(UnresolvedExpressionTypeAccess::class) + if (result.rhs.coneTypeOrNull?.isNothing == true) { + val lhsType = result.lhs.resolvedType + // Converting to non-raw type is necessary to preserver the K1 semantics (see KT-54526) + val newReturnType = + lhsType.makeConeTypeDefinitelyNotNullOrNotNull(session.typeContext) + .convertToNonRawVersion() + result.replaceConeTypeOrNull(newReturnType) + isLhsNotNull = true } session.typeContext.run { - if (result.coneTypeSafe()?.isNullableType() == true - && result.rhs.coneTypeSafe()?.isNullableType() == false - ) { + if (result.resolvedType.isNullableType() && !result.rhs.resolvedType.isNullableType()) { // Sometimes return type for special call for elvis operator might be nullable, // but result is not nullable if the right type is not nullable result.replaceConeTypeOrNull( diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index 313d0a62991..d8a677d9d78 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -233,8 +233,8 @@ open class FirDeclarationsResolveTransformer( // get() = delegate.getValue(thisRef, kProperty: KProperty0/1/2<..., SomeType>) // set() = delegate.getValue(thisRef, kProperty: KProperty0/1/2<..., SomeType>, value) val propertyReferenceAccess = resolvedArgumentMapping?.keys?.toList()?.getOrNull(1) as? FirCallableReferenceAccess ?: return - val type = propertyReferenceAccess.coneTypeOrNull - if (type != null && property.returnTypeRef is FirResolvedTypeRef) { + val type = propertyReferenceAccess.resolvedType + if (property.returnTypeRef is FirResolvedTypeRef) { val typeArguments = (type.type as ConeClassLikeType).typeArguments val extensionType = property.receiverParameter?.typeRef?.coneType val dispatchType = context.containingClass?.let { containingClass -> @@ -763,7 +763,7 @@ open class FirDeclarationsResolveTransformer( if (result.returnTypeRef is FirImplicitTypeRef) { val simpleFunction = function as? FirSimpleFunction val returnExpression = (body?.statements?.singleOrNull() as? FirReturnExpression)?.result - val expressionType = returnExpression?.coneTypeOrNull + val expressionType = returnExpression?.resolvedType val returnTypeRef = expressionType ?.toFirResolvedTypeRef(result.returnTypeRef.source) ?.approximateDeclarationType( @@ -1104,7 +1104,7 @@ open class FirDeclarationsResolveTransformer( val inferredType = if (backingField is FirDefaultPropertyBackingField) { propertyType } else { - backingField.initializer?.unwrapSmartcastExpression()?.coneTypeOrNull?.toFirResolvedTypeRef() + backingField.initializer?.unwrapSmartcastExpression()?.resolvedType?.toFirResolvedTypeRef() } val resultType = inferredType ?: return backingField.transformReturnTypeRef( @@ -1133,7 +1133,7 @@ open class FirDeclarationsResolveTransformer( val resultType = when { initializer != null -> { val unwrappedInitializer = initializer.unwrapSmartcastExpression() - unwrappedInitializer.resultType?.toFirResolvedTypeRef() + unwrappedInitializer.resolvedType.toFirResolvedTypeRef() } variable.getter != null && variable.getter !is FirDefaultPropertyAccessor -> variable.getter?.returnTypeRef else -> null @@ -1216,10 +1216,10 @@ open class FirDeclarationsResolveTransformer( private val FirVariable.initializerResolved: Boolean get() { val initializer = initializer ?: return false - return initializer.coneTypeOrNull != null && initializer !is FirErrorExpression + return initializer.isResolved && initializer !is FirErrorExpression } protected val FirFunction.bodyResolved: Boolean - get() = body !is FirLazyBlock && body?.coneTypeOrNull != null + get() = body !is FirLazyBlock && body?.isResolved == true } 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 e94d11f013f..4e8af891a79 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 @@ -68,7 +68,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT } override fun transformExpression(expression: FirExpression, data: ResolutionMode): FirStatement { - if (expression.resultType == null && expression !is FirWrappedExpression) { + if (!expression.isResolved && expression !is FirWrappedExpression) { expression.resultType = ConeErrorType( ConeSimpleDiagnostic( "Type calculating for ${expression::class} is not supported", @@ -95,7 +95,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT data: ResolutionMode, isUsedAsReceiver: Boolean, ): FirStatement { - if (qualifiedAccessExpression.coneTypeOrNull != null && qualifiedAccessExpression.calleeReference !is FirSimpleNamedReference) { + if (qualifiedAccessExpression.isResolved && qualifiedAccessExpression.calleeReference !is FirSimpleNamedReference) { return qualifiedAccessExpression } @@ -134,12 +134,12 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT } is FirDelegateFieldReference -> { val delegateFieldSymbol = callee.resolvedSymbol - qualifiedAccessExpression.resultType = delegateFieldSymbol.fir.delegate!!.coneTypeOrNull + qualifiedAccessExpression.resultType = delegateFieldSymbol.fir.delegate!!.resolvedType qualifiedAccessExpression } is FirResolvedNamedReference, is FirErrorNamedReference -> { - if (qualifiedAccessExpression.coneTypeOrNull == null) { + if (!qualifiedAccessExpression.isResolved) { storeTypeFromCallee(qualifiedAccessExpression, isLhsOfAssignment = false) } qualifiedAccessExpression @@ -395,7 +395,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT val calleeReference = functionCall.calleeReference if ( (calleeReference is FirResolvedNamedReference || calleeReference is FirErrorNamedReference) && - functionCall.resultType == null + !functionCall.isResolved ) { storeTypeFromCallee(functionCall, isLhsOfAssignment = false) } @@ -724,7 +724,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT source = desugaredSource, name = name, initializer = initializer, - typeRef = initializer.coneTypeOrNull?.toFirResolvedTypeRef(desugaredSource), + typeRef = initializer.resolvedType.toFirResolvedTypeRef(desugaredSource), ) fun buildAndResolveOperatorCall(receiver: FirExpression): FirFunctionCall = buildFunctionCall { @@ -781,7 +781,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT statements += unaryVariable.toQualifiedAccess() } }.apply { - replaceConeTypeOrNull((statements.last() as FirExpression).coneTypeOrNull) + replaceConeTypeOrNull((statements.last() as FirExpression).resolvedType) } return if (originalExpression is FirSafeCallExpression) { @@ -840,7 +840,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT val firClass = type.lookupTag.toSymbol(session)?.fir ?: return this if (firClass.typeParameters.isEmpty()) return this - val originalType = argument.unwrapSmartcastExpression().coneTypeSafe() ?: return this + val originalType = argument.unwrapSmartcastExpression().resolvedType val newType = components.computeRepresentativeTypeForBareType(type, originalType) ?: if (firClass.isLocal && (operation == FirOperation.AS || operation == FirOperation.SAFE_AS)) { (firClass as FirClass).defaultType() @@ -937,7 +937,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT // fun checkNotNull(arg: K?): K // ...in order to get the not-nullable type of the argument. - if (checkNotNullCall.calleeReference is FirResolvedNamedReference && checkNotNullCall.resultType != null) { + if (checkNotNullCall.calleeReference is FirResolvedNamedReference && checkNotNullCall.isResolved) { return checkNotNullCall } @@ -981,7 +981,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference ) ?: typeFromCallee.type } else { - desugaredAssignmentValueReferenceExpression.resultType = referencedExpression.resultType + desugaredAssignmentValueReferenceExpression.resultType = referencedExpression.resolvedType } return desugaredAssignmentValueReferenceExpression } @@ -1022,7 +1022,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT val result = variableAssignment.transformRValue( transformer, withExpectedType( - variableAssignment.lValue.coneTypeOrNull?.toFirResolvedTypeRef() ?: FirImplicitTypeRefImplWithoutSource, + variableAssignment.lValue.resolvedType.toFirResolvedTypeRef(), expectedTypeMismatchIsReportedInChecker = true ), ) @@ -1130,11 +1130,11 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT } else -> { if (!shouldComputeTypeOfGetClassCallWithNotQualifierInLhs(getClassCall)) return transformedGetClassCall - val resultType = lhs.resultType + val resultType = lhs.resolvedType if (resultType is ConeErrorType) { resultType } else { - ConeKotlinTypeProjectionOut(resultType!!) + ConeKotlinTypeProjectionOut(resultType) } } } @@ -1291,6 +1291,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT .resolveDelegatingConstructorCall(delegatedConstructorCall, constructorType, containingClass.symbol.toLookupTag()) if (reference is FirThisReference && reference.boundSymbol == null) { + @OptIn(UnresolvedExpressionTypeAccess::class) resolvedCall.dispatchReceiver?.coneTypeSafe()?.lookupTag?.toSymbol(session)?.let { reference.replaceBoundSymbol(it) } @@ -1518,7 +1519,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT source = lhsGetCall.explicitReceiver?.source?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment), name = SpecialNames.ARRAY, initializer = initializer, - typeRef = initializer.coneTypeOrNull?.toFirResolvedTypeRef(initializer.source?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment)), + typeRef = initializer.resolvedType.toFirResolvedTypeRef(initializer.source?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment)), ) val indexVariables = lhsGetCall.arguments.flatMap { @@ -1532,7 +1533,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT source = index.source?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment), name = SpecialNames.subscribeOperatorIndex(i), initializer = index, - typeRef = index.coneTypeOrNull?.toFirResolvedTypeRef(), + typeRef = index.resolvedType.toFirResolvedTypeRef(), ) } @@ -1562,7 +1563,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT arguments += indicesQualifiedAccess.subList(i, i + varargSize) i += varargSize source = argument.source - coneTypeOrNull = argument.coneTypeOrNull + coneTypeOrNull = argument.resolvedType varargElementType = argument.varargElementType } } else { @@ -1571,7 +1572,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT } } origin = FirFunctionCallOrigin.Operator - coneTypeOrNull = lhsGetCall.coneTypeOrNull + coneTypeOrNull = lhsGetCall.resolvedType } val generator = GeneratorOfPlusAssignCalls( @@ -1649,7 +1650,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT data: ResolutionMode, ): FirStatement { anonymousObjectExpression.transformAnonymousObject(transformer, data) - if (anonymousObjectExpression.coneTypeOrNull == null) { + if (!anonymousObjectExpression.isResolved) { anonymousObjectExpression.resultType = anonymousObjectExpression.anonymousObject.defaultType() } dataFlowAnalyzer.exitAnonymousObjectExpression(anonymousObjectExpression) diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/VariableStorageImpl.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/VariableStorageImpl.kt index aeb2414d9b8..afbf874495a 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/VariableStorageImpl.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/VariableStorageImpl.kt @@ -179,6 +179,8 @@ class VariableStorageImpl(private val session: FirSession) : VariableStorage() { property.visibility == Visibilities.Private -> PropertyStability.STABLE_VALUE property.modality != Modality.FINAL -> { val dispatchReceiver = (originalFir.unwrapElement() as? FirQualifiedAccessExpression)?.dispatchReceiver ?: return null + + @OptIn(UnresolvedExpressionTypeAccess::class) val receiverType = dispatchReceiver.coneTypeSafe()?.fullyExpandedType(session) ?: return null val receiverSymbol = receiverType.lookupTag.toSymbol(session) ?: return null when (val receiverFir = receiverSymbol.fir) { diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNode.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNode.kt index b13ff919f27..f36556d46f9 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNode.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNode.kt @@ -860,6 +860,7 @@ class WhenSubjectExpressionExitNode(owner: ControlFlowGraph, override val fir: F object FirStub : FirExpression() { override val source: KtSourceElement? get() = null + @UnresolvedExpressionTypeAccess override val coneTypeOrNull: ConeKotlinType = StandardClassIds.Nothing.constructClassLikeType() override val annotations: List get() = listOf() diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/transformers/publishedApiEffectiveVisibility.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/transformers/publishedApiEffectiveVisibility.kt index f4cdbb0734d..f1260e25185 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/transformers/publishedApiEffectiveVisibility.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/transformers/publishedApiEffectiveVisibility.kt @@ -12,16 +12,16 @@ import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.classId import org.jetbrains.kotlin.fir.declarations.utils.effectiveVisibility import org.jetbrains.kotlin.fir.expressions.FirAnnotation +import org.jetbrains.kotlin.fir.expressions.UnresolvedExpressionTypeAccess import org.jetbrains.kotlin.fir.expressions.unexpandedClassId import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.toEffectiveVisibility import org.jetbrains.kotlin.fir.types.ConeClassLikeType -import org.jetbrains.kotlin.fir.types.coneTypeSafe +import org.jetbrains.kotlin.fir.types.resolvedType import org.jetbrains.kotlin.fir.types.toLookupTag import org.jetbrains.kotlin.fir.types.typeContext import org.jetbrains.kotlin.name.StandardClassIds @@ -57,7 +57,7 @@ fun computePublishedApiEffectiveVisibility( session: FirSession, ): EffectiveVisibility? { val hasPublishedApiAnnotation = annotations.any { - it.coneTypeSafe()?.lookupTag?.classId == StandardClassIds.Annotations.PublishedApi + (it.resolvedType as? ConeClassLikeType)?.lookupTag?.classId == StandardClassIds.Annotations.PublishedApi } return computePublishedApiEffectiveVisibility(