[FIR] Fix resolving to star import member instead of builtin (^KT-48157 Fixed)

This commit is contained in:
Ivan Kochurkin
2021-08-19 22:43:57 +03:00
committed by Space
parent bb27ae2b42
commit 34cc7e5199
23 changed files with 262 additions and 137 deletions
@@ -23,7 +23,7 @@ FILE: classifierAccessFromCompanion.kt
super<R|kotlin/Any|>() super<R|kotlin/Any|>()
} }
public final val f: R|kotlin/Unit| = Q|Factory.Function| public final val f: R|kotlin/Unit| = R|kotlin/Unit|
public get(): R|kotlin/Unit| public get(): R|kotlin/Unit|
public final val x: R|Factory.Function.Default| = Q|Factory.Function.Default| public final val x: R|Factory.Function.Default| = Q|Factory.Function.Default|
@@ -12,7 +12,7 @@ FILE: innerQualifier.kt
} }
} }
public final val x: R|kotlin/Unit| = Q|Outer.Inner| public final val x: R|kotlin/Unit| = R|kotlin/Unit|
public get(): R|kotlin/Unit| public get(): R|kotlin/Unit|
public final val klass: R|kotlin/reflect/KClass<Outer.Inner>| = <getClass>(Q|Outer.Inner|) public final val klass: R|kotlin/reflect/KClass<Outer.Inner>| = <getClass>(Q|Outer.Inner|)
public get(): R|kotlin/reflect/KClass<Outer.Inner>| public get(): R|kotlin/reflect/KClass<Outer.Inner>|
@@ -59,8 +59,8 @@ FILE: qualifierPriority.kt
} }
public final val def: R|D.E.F| = Q|D.E.F| public final val def: R|D.E.F| = Q|D.E.F|
public get(): R|D.E.F| public get(): R|D.E.F|
public final val de: R|kotlin/Unit| = Q|D.E| public final val de: R|kotlin/String| = Q|D|.R|/E|
public get(): R|kotlin/Unit| public get(): R|kotlin/String|
public final enum class G : R|kotlin/Enum<G>| { public final enum class G : R|kotlin/Enum<G>| {
private constructor(): R|G| { private constructor(): R|G| {
super<R|kotlin/Enum<G>|>() super<R|kotlin/Enum<G>|>()
@@ -24,7 +24,7 @@ val D.E get() = ""
val def = D.E.F // object val def = D.E.F // object
// See KT-46409 // See KT-46409
val de = D.<!NO_COMPANION_OBJECT!>E<!> // Should be: extension & no error, in fact: qualifier val de = D.E
enum class G { enum class G {
H; H;
@@ -24117,6 +24117,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/resolve/resolveAnnotatedLambdaArgument.kt"); runTest("compiler/testData/diagnostics/tests/resolve/resolveAnnotatedLambdaArgument.kt");
} }
@Test
@TestMetadata("resolveToStarImportMemberInsteadOfBuiltin.kt")
public void testResolveToStarImportMemberInsteadOfBuiltin() throws Exception {
runTest("compiler/testData/diagnostics/tests/resolve/resolveToStarImportMemberInsteadOfBuiltin.kt");
}
@Test @Test
@TestMetadata("resolveTypeArgsForUnresolvedCall.kt") @TestMetadata("resolveTypeArgsForUnresolvedCall.kt")
public void testResolveTypeArgsForUnresolvedCall() throws Exception { public void testResolveTypeArgsForUnresolvedCall() throws Exception {
@@ -24117,6 +24117,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/resolve/resolveAnnotatedLambdaArgument.kt"); runTest("compiler/testData/diagnostics/tests/resolve/resolveAnnotatedLambdaArgument.kt");
} }
@Test
@TestMetadata("resolveToStarImportMemberInsteadOfBuiltin.kt")
public void testResolveToStarImportMemberInsteadOfBuiltin() throws Exception {
runTest("compiler/testData/diagnostics/tests/resolve/resolveToStarImportMemberInsteadOfBuiltin.kt");
}
@Test @Test
@TestMetadata("resolveTypeArgsForUnresolvedCall.kt") @TestMetadata("resolveTypeArgsForUnresolvedCall.kt")
public void testResolveTypeArgsForUnresolvedCall() throws Exception { public void testResolveTypeArgsForUnresolvedCall() throws Exception {
@@ -44,6 +44,7 @@ private fun ConeDiagnostic.toFirDiagnostic(
is ConeFunctionExpectedError -> FirErrors.FUNCTION_EXPECTED.createOn(source, this.expression, this.type) is ConeFunctionExpectedError -> FirErrors.FUNCTION_EXPECTED.createOn(source, this.expression, this.type)
is ConeResolutionToClassifierError -> FirErrors.RESOLUTION_TO_CLASSIFIER.createOn(source, this.classSymbol) is ConeResolutionToClassifierError -> FirErrors.RESOLUTION_TO_CLASSIFIER.createOn(source, this.classSymbol)
is ConeHiddenCandidateError -> FirErrors.INVISIBLE_REFERENCE.createOn(source, this.candidateSymbol) is ConeHiddenCandidateError -> FirErrors.INVISIBLE_REFERENCE.createOn(source, this.candidateSymbol)
is ConeNoCompanionObject -> FirErrors.NO_COMPANION_OBJECT.createOn(source, this.symbol)
is ConeAmbiguityError -> when { is ConeAmbiguityError -> when {
applicability.isSuccess -> FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY.createOn(source, this.candidates.map { it.symbol }) applicability.isSuccess -> FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY.createOn(source, this.candidates.map { it.symbol })
applicability == CandidateApplicability.UNSAFE_CALL -> { applicability == CandidateApplicability.UNSAFE_CALL -> {
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
import java.lang.annotation.ElementType
class FirCallResolver( class FirCallResolver(
private val components: FirAbstractBodyResolveTransformer.BodyResolveTransformerComponents, private val components: FirAbstractBodyResolveTransformer.BodyResolveTransformerComponents,
@@ -73,7 +74,7 @@ class FirCallResolver(
qualifiedResolver.reset() qualifiedResolver.reset()
@Suppress("NAME_SHADOWING") @Suppress("NAME_SHADOWING")
val functionCall = if (needTransformArguments) { val functionCall = if (needTransformArguments) {
functionCall.transformExplicitReceiver() components.context.withIncrementedQualifierPartIndex { functionCall.transformExplicitReceiver() }
.also { .also {
components.dataFlowAnalyzer.enterQualifiedAccessExpression() components.dataFlowAnalyzer.enterQualifiedAccessExpression()
functionCall.argumentList.transformArguments(transformer, ResolutionMode.ContextDependent) functionCall.argumentList.transformArguments(transformer, ResolutionMode.ContextDependent)
@@ -82,51 +83,53 @@ class FirCallResolver(
functionCall functionCall
} }
val name = functionCall.calleeReference.name return components.context.withIncrementedQualifierPartIndex {
val result = collectCandidates(functionCall, name) val name = functionCall.calleeReference.name
val result = collectCandidates(functionCall, name)
var forceCandidates: Collection<Candidate>? = null var forceCandidates: Collection<Candidate>? = null
if (result.candidates.isEmpty()) { if (result.candidates.isEmpty()) {
val newResult = collectCandidates(functionCall, name, CallKind.VariableAccess) val newResult = collectCandidates(functionCall, name, CallKind.VariableAccess)
if (newResult.candidates.isNotEmpty()) { if (newResult.candidates.isNotEmpty()) {
forceCandidates = newResult.candidates forceCandidates = newResult.candidates
}
} }
}
val nameReference = createResolvedNamedReference( val nameReference = createResolvedNamedReference(
functionCall.calleeReference, functionCall.calleeReference,
name, name,
result.info, result.info,
result.candidates, result.candidates,
result.applicability, result.applicability,
functionCall.explicitReceiver, functionCall.explicitReceiver,
expectedCallKind = if (forceCandidates != null) CallKind.VariableAccess else null, expectedCallKind = if (forceCandidates != null) CallKind.VariableAccess else null,
expectedCandidates = forceCandidates expectedCandidates = forceCandidates
)
val resultExpression = functionCall.transformCalleeReference(StoreNameReference, nameReference)
val candidate = (nameReference as? FirNamedReferenceWithCandidate)?.candidate
val resolvedReceiver = functionCall.explicitReceiver
if (candidate != null && resolvedReceiver is FirResolvedQualifier) {
resolvedReceiver.replaceResolvedToCompanionObject(candidate.isFromCompanionObjectTypeScope)
}
// We need desugaring
val resultFunctionCall = if (candidate != null && candidate.callInfo != result.info) {
functionCall.copy(
explicitReceiver = candidate.callInfo.explicitReceiver,
dispatchReceiver = candidate.dispatchReceiverExpression(),
extensionReceiver = candidate.extensionReceiverExpression(),
argumentList = candidate.callInfo.argumentList,
) )
} else {
resultExpression val resultExpression = functionCall.transformCalleeReference(StoreNameReference, nameReference)
val candidate = (nameReference as? FirNamedReferenceWithCandidate)?.candidate
val resolvedReceiver = functionCall.explicitReceiver
if (candidate != null && resolvedReceiver is FirResolvedQualifier) {
resolvedReceiver.replaceResolvedToCompanionObject(candidate.isFromCompanionObjectTypeScope)
}
// We need desugaring
val resultFunctionCall = if (candidate != null && candidate.callInfo != result.info) {
functionCall.copy(
explicitReceiver = candidate.callInfo.explicitReceiver,
dispatchReceiver = candidate.dispatchReceiverExpression(),
extensionReceiver = candidate.extensionReceiverExpression(),
argumentList = candidate.callInfo.argumentList,
)
} else {
resultExpression
}
val typeRef = components.typeFromCallee(resultFunctionCall)
if (typeRef.type is ConeKotlinErrorType) {
resultFunctionCall.resultType = typeRef
}
return@withIncrementedQualifierPartIndex resultFunctionCall
} }
val typeRef = components.typeFromCallee(resultFunctionCall)
if (typeRef.type is ConeKotlinErrorType) {
resultFunctionCall.resultType = typeRef
}
return resultFunctionCall
} }
private inline fun <reified Q : FirQualifiedAccess> Q.transformExplicitReceiver(): Q { private inline fun <reified Q : FirQualifiedAccess> Q.transformExplicitReceiver(): Q {
@@ -216,97 +219,99 @@ class FirCallResolver(
): FirStatement { ): FirStatement {
val callee = qualifiedAccess.calleeReference as? FirSimpleNamedReference ?: return qualifiedAccess val callee = qualifiedAccess.calleeReference as? FirSimpleNamedReference ?: return qualifiedAccess
qualifiedResolver.initProcessingQualifiedAccess(callee, qualifiedAccess.typeArguments) return components.context.withIncrementedQualifierPartIndex {
qualifiedResolver.initProcessingQualifiedAccess(callee, qualifiedAccess.typeArguments)
@Suppress("NAME_SHADOWING") @Suppress("NAME_SHADOWING")
val qualifiedAccess = qualifiedAccess.transformExplicitReceiver<FirQualifiedAccess>() val qualifiedAccess = qualifiedAccess.transformExplicitReceiver<FirQualifiedAccess>()
qualifiedResolver.replacedQualifier(qualifiedAccess)?.let { resolvedQualifierPart -> qualifiedResolver.replacedQualifier(qualifiedAccess)?.let { resolvedQualifierPart ->
return resolvedQualifierPart return@withIncrementedQualifierPartIndex resolvedQualifierPart
} }
var result = collectCandidates(qualifiedAccess, callee.name) var result = collectCandidates(qualifiedAccess, callee.name)
if (qualifiedAccess.explicitReceiver == null) { if (qualifiedAccess.explicitReceiver == null) {
if (!result.applicability.isSuccess) { if (!result.applicability.isSuccess) {
// We should run QualifierResolver if no successful candidates are available // We should run QualifierResolver if no successful candidates are available
// Otherwise expression (even ambiguous) beat qualifier // Otherwise expression (even ambiguous) beat qualifier
qualifiedResolver.tryResolveAsQualifier(qualifiedAccess.source)?.let { resolvedQualifier -> qualifiedResolver.tryResolveAsQualifier(qualifiedAccess.source)?.let { resolvedQualifier ->
return resolvedQualifier return@withIncrementedQualifierPartIndex resolvedQualifier
}
}
qualifiedResolver.reset()
}
var functionCallExpected = false
if (result.candidates.isEmpty() && qualifiedAccess !is FirFunctionCall) {
val newResult = collectCandidates(qualifiedAccess, callee.name, CallKind.Function)
if (newResult.candidates.isNotEmpty()) {
result = newResult
functionCallExpected = true
} }
} }
qualifiedResolver.reset()
}
var functionCallExpected = false val reducedCandidates = result.candidates
if (result.candidates.isEmpty() && qualifiedAccess !is FirFunctionCall) { if (!acceptCandidates(reducedCandidates)) return@withIncrementedQualifierPartIndex qualifiedAccess
val newResult = collectCandidates(qualifiedAccess, callee.name, CallKind.Function)
if (newResult.candidates.isNotEmpty()) { val nameReference = createResolvedNamedReference(
result = newResult callee,
functionCallExpected = true callee.name,
result.info,
reducedCandidates,
result.applicability,
qualifiedAccess.explicitReceiver,
expectedCallKind = if (functionCallExpected) CallKind.Function else null
)
val referencedSymbol = when (nameReference) {
is FirResolvedNamedReference -> nameReference.resolvedSymbol
is FirNamedReferenceWithCandidate -> nameReference.candidateSymbol
else -> null
} }
}
val reducedCandidates = result.candidates val diagnostic = when (nameReference) {
if (!acceptCandidates(reducedCandidates)) return qualifiedAccess is FirErrorReferenceWithCandidate -> nameReference.diagnostic
is FirErrorNamedReference -> nameReference.diagnostic
else -> null
}
val nameReference = createResolvedNamedReference( (qualifiedAccess.explicitReceiver as? FirResolvedQualifier)?.replaceResolvedToCompanionObject(
callee, reducedCandidates.isNotEmpty() && reducedCandidates.all { it.isFromCompanionObjectTypeScope }
callee.name, )
result.info,
reducedCandidates,
result.applicability,
qualifiedAccess.explicitReceiver,
expectedCallKind = if (functionCallExpected) CallKind.Function else null
)
val referencedSymbol = when (nameReference) { when {
is FirResolvedNamedReference -> nameReference.resolvedSymbol referencedSymbol is FirClassLikeSymbol<*> -> {
is FirNamedReferenceWithCandidate -> nameReference.candidateSymbol return@withIncrementedQualifierPartIndex components.buildResolvedQualifierForClass(
else -> null
}
val diagnostic = when (nameReference) {
is FirErrorReferenceWithCandidate -> nameReference.diagnostic
is FirErrorNamedReference -> nameReference.diagnostic
else -> null
}
(qualifiedAccess.explicitReceiver as? FirResolvedQualifier)?.replaceResolvedToCompanionObject(
reducedCandidates.isNotEmpty() && reducedCandidates.all { it.isFromCompanionObjectTypeScope }
)
when {
referencedSymbol is FirClassLikeSymbol<*> -> {
return components.buildResolvedQualifierForClass(
referencedSymbol,
nameReference.source,
qualifiedAccess.typeArguments,
diagnostic,
nonFatalDiagnostics = extractNonFatalDiagnostics(
nameReference.source,
qualifiedAccess.explicitReceiver,
referencedSymbol, referencedSymbol,
(qualifiedAccess as? FirPropertyAccessExpression)?.nonFatalDiagnostics nameReference.source,
qualifiedAccess.typeArguments,
diagnostic,
nonFatalDiagnostics = extractNonFatalDiagnostics(
nameReference.source,
qualifiedAccess.explicitReceiver,
referencedSymbol,
(qualifiedAccess as? FirPropertyAccessExpression)?.nonFatalDiagnostics
)
) )
) }
} referencedSymbol is FirTypeParameterSymbol && referencedSymbol.fir.isReified -> {
referencedSymbol is FirTypeParameterSymbol && referencedSymbol.fir.isReified -> { return@withIncrementedQualifierPartIndex buildResolvedReifiedParameterReference {
return buildResolvedReifiedParameterReference { source = nameReference.source
source = nameReference.source symbol = referencedSymbol
symbol = referencedSymbol typeRef = typeForReifiedParameterReference(this)
typeRef = typeForReifiedParameterReference(this) }
} }
} }
}
var resultExpression = qualifiedAccess.transformCalleeReference(StoreNameReference, nameReference) var resultExpression = qualifiedAccess.transformCalleeReference(StoreNameReference, nameReference)
if (reducedCandidates.size == 1) { if (reducedCandidates.size == 1) {
val candidate = reducedCandidates.single() val candidate = reducedCandidates.single()
resultExpression = resultExpression.transformDispatchReceiver(StoreReceiver, candidate.dispatchReceiverExpression()) resultExpression = resultExpression.transformDispatchReceiver(StoreReceiver, candidate.dispatchReceiverExpression())
resultExpression = resultExpression.transformExtensionReceiver(StoreReceiver, candidate.extensionReceiverExpression()) resultExpression = resultExpression.transformExtensionReceiver(StoreReceiver, candidate.extensionReceiverExpression())
}
if (resultExpression is FirExpression) transformer.storeTypeFromCallee(resultExpression)
return@withIncrementedQualifierPartIndex resultExpression
} }
if (resultExpression is FirExpression) transformer.storeTypeFromCallee(resultExpression)
return resultExpression
} }
private fun extractNonFatalDiagnostics( private fun extractNonFatalDiagnostics(
@@ -700,6 +705,7 @@ class FirCallResolver(
val candidate = candidates.single() val candidate = candidates.single()
val diagnostic = when (applicability) { val diagnostic = when (applicability) {
CandidateApplicability.HIDDEN -> ConeHiddenCandidateError(candidate.symbol) CandidateApplicability.HIDDEN -> ConeHiddenCandidateError(candidate.symbol)
CandidateApplicability.NO_COMPANION_OBJECT -> ConeNoCompanionObject(candidate.symbol as FirRegularClassSymbol)
else -> ConeInapplicableCandidateError(applicability, candidate) else -> ConeInapplicableCandidateError(applicability, candidate)
} }
createErrorReferenceWithExistingCandidate( createErrorReferenceWithExistingCandidate(
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.resolve.calls package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
@@ -48,7 +49,8 @@ class CandidateFactory private constructor(
scope: FirScope?, scope: FirScope?,
dispatchReceiverValue: ReceiverValue? = null, dispatchReceiverValue: ReceiverValue? = null,
extensionReceiverValue: ReceiverValue? = null, extensionReceiverValue: ReceiverValue? = null,
builtInExtensionFunctionReceiverValue: ReceiverValue? = null builtInExtensionFunctionReceiverValue: ReceiverValue? = null,
objectsByName: Boolean = false
): Candidate { ): Candidate {
val result = Candidate( val result = Candidate(
symbol, dispatchReceiverValue, extensionReceiverValue, symbol, dispatchReceiverValue, extensionReceiverValue,
@@ -72,6 +74,13 @@ class CandidateFactory private constructor(
if (symbol is FirValueParameterSymbol || symbol is FirPropertySymbol && symbol.isLocal || symbol is FirBackingFieldSymbol) { if (symbol is FirValueParameterSymbol || symbol is FirPropertySymbol && symbol.isLocal || symbol is FirBackingFieldSymbol) {
result.addDiagnostic(Unsupported("References to variables aren't supported yet", callSite.calleeReference.source)) result.addDiagnostic(Unsupported("References to variables aren't supported yet", callSite.calleeReference.source))
} }
} else if (objectsByName &&
context.bodyResolveContext.qualifierPartIndexFromEnd == 0 &&
symbol is FirRegularClassSymbol &&
symbol.classKind != ClassKind.OBJECT &&
symbol.companionObjectSymbol == null
) {
result.addDiagnostic(NoCompanionObject)
} }
return result return result
} }
@@ -70,6 +70,8 @@ class InapplicableWrongReceiver(
val actualType: ConeKotlinType? = null, val actualType: ConeKotlinType? = null,
) : ResolutionDiagnostic(INAPPLICABLE_WRONG_RECEIVER) ) : ResolutionDiagnostic(INAPPLICABLE_WRONG_RECEIVER)
object NoCompanionObject : ResolutionDiagnostic(NO_COMPANION_OBJECT)
class UnsafeCall(val actualType: ConeKotlinType) : ResolutionDiagnostic(UNSAFE_CALL) class UnsafeCall(val actualType: ConeKotlinType) : ResolutionDiagnostic(UNSAFE_CALL)
object LowerPriorityToPreserveCompatibilityDiagnostic : ResolutionDiagnostic(RESOLVED_NEED_PRESERVE_COMPATIBILITY) object LowerPriorityToPreserveCompatibilityDiagnostic : ResolutionDiagnostic(RESOLVED_NEED_PRESERVE_COMPATIBILITY)
@@ -76,7 +76,8 @@ private class TowerScopeLevelProcessor(
dispatchReceiverValue: ReceiverValue?, dispatchReceiverValue: ReceiverValue?,
extensionReceiverValue: ReceiverValue?, extensionReceiverValue: ReceiverValue?,
scope: FirScope, scope: FirScope,
builtInExtensionFunctionReceiverValue: ReceiverValue? builtInExtensionFunctionReceiverValue: ReceiverValue?,
objectsByName: Boolean
) { ) {
resultCollector.consumeCandidate( resultCollector.consumeCandidate(
group, candidateFactory.createCandidate( group, candidateFactory.createCandidate(
@@ -86,7 +87,8 @@ private class TowerScopeLevelProcessor(
scope, scope,
dispatchReceiverValue, dispatchReceiverValue,
extensionReceiverValue, extensionReceiverValue,
builtInExtensionFunctionReceiverValue builtInExtensionFunctionReceiverValue,
objectsByName
), candidateFactory.context ), candidateFactory.context
) )
} }
@@ -52,7 +52,8 @@ abstract class TowerScopeLevel {
dispatchReceiverValue: ReceiverValue?, dispatchReceiverValue: ReceiverValue?,
extensionReceiverValue: ReceiverValue?, extensionReceiverValue: ReceiverValue?,
scope: FirScope, scope: FirScope,
builtInExtensionFunctionReceiverValue: ReceiverValue? = null builtInExtensionFunctionReceiverValue: ReceiverValue? = null,
objectsByName: Boolean = false
) )
} }
} }
@@ -335,7 +336,8 @@ class ScopeTowerLevel(
processor.consumeCandidate( processor.consumeCandidate(
it, dispatchReceiverValue = null, it, dispatchReceiverValue = null,
extensionReceiverValue = null, extensionReceiverValue = null,
scope = scope scope = scope,
objectsByName = true
) )
} }
return if (empty) ProcessResult.SCOPE_EMPTY else ProcessResult.FOUND return if (empty) ProcessResult.SCOPE_EMPTY else ProcessResult.FOUND
@@ -70,6 +70,12 @@ class ConeInapplicableCandidateError(
override val reason: String get() = "Inapplicable($applicability): ${describeSymbol(candidate.symbol)}" override val reason: String get() = "Inapplicable($applicability): ${describeSymbol(candidate.symbol)}"
} }
class ConeNoCompanionObject(
val symbol: FirRegularClassSymbol
) : ConeDiagnostic() {
override val reason: String get() = "Classifier ''$symbol'' does not have a companion object, and thus must be initialized here"
}
class ConeConstraintSystemHasContradiction( class ConeConstraintSystemHasContradiction(
val candidate: Candidate, val candidate: Candidate,
) : ConeDiagnostic() { ) : ConeDiagnostic() {
@@ -75,7 +75,7 @@ class BodyResolveContext(
get() = towerDataContextsForClassParts.towerDataContextForCallableReferences get() = towerDataContextsForClassParts.towerDataContextForCallableReferences
@set:PrivateForInline @set:PrivateForInline
var containers: MutableList<FirDeclaration> = mutableListOf() var containers: ArrayDeque<FirDeclaration> = ArrayDeque()
@set:PrivateForInline @set:PrivateForInline
var containingClass: FirRegularClass? = null var containingClass: FirRegularClass? = null
@@ -118,7 +118,7 @@ class BodyResolveContext(
return try { return try {
f() f()
} finally { } finally {
containers.removeAt(containers.size - 1) containers.removeLast()
} }
} }
@@ -130,7 +130,7 @@ class BodyResolveContext(
return try { return try {
f() f()
} finally { } finally {
containers.removeAt(containers.size - 1) containers.removeLast()
containingClass = oldContainingClass containingClass = oldContainingClass
} }
} }
@@ -172,6 +172,17 @@ class BodyResolveContext(
} }
} }
var qualifierPartIndexFromEnd: Int = -1
inline fun <R> withIncrementedQualifierPartIndex(l: () -> R): R {
qualifierPartIndexFromEnd++
return try {
l()
} finally {
qualifierPartIndexFromEnd--
}
}
@PrivateForInline @PrivateForInline
fun replaceTowerDataContext(newContext: FirTowerDataContext) { fun replaceTowerDataContext(newContext: FirTowerDataContext) {
towerDataContextsForClassParts.currentContext = newContext towerDataContextsForClassParts.currentContext = newContext
@@ -837,9 +837,11 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
callableReferenceAccess.transformAnnotations(transformer, data) callableReferenceAccess.transformAnnotations(transformer, data)
val explicitReceiver = callableReferenceAccess.explicitReceiver val explicitReceiver = callableReferenceAccess.explicitReceiver
val transformedLHS = explicitReceiver?.transformSingle(this, ResolutionMode.ContextIndependent)?.apply { val transformedLHS = context.withIncrementedQualifierPartIndex {
if (this is FirResolvedQualifier && callableReferenceAccess.hasQuestionMarkAtLHS) { explicitReceiver?.transformSingle(this, ResolutionMode.ContextIndependent)?.apply {
replaceIsNullableLHSForCallableReference(true) if (this is FirResolvedQualifier && callableReferenceAccess.hasQuestionMarkAtLHS) {
replaceIsNullableLHSForCallableReference(true)
}
} }
} }
@@ -867,7 +869,10 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
} else { } else {
data data
} }
val transformedGetClassCall = transformExpression(getClassCall, dataWithExpectedType) as FirGetClassCall
val transformedGetClassCall = context.withIncrementedQualifierPartIndex {
transformExpression(getClassCall, dataWithExpectedType) as FirGetClassCall
}
val typeOfExpression = when (val lhs = transformedGetClassCall.argument) { val typeOfExpression = when (val lhs = transformedGetClassCall.argument) {
is FirResolvedQualifier -> { is FirResolvedQualifier -> {
@@ -13,6 +13,7 @@ enum class CandidateApplicability {
INAPPLICABLE_ARGUMENTS_MAPPING_ERROR, // arguments not mapped to parameters (i.e. different size of arguments and parameters) INAPPLICABLE_ARGUMENTS_MAPPING_ERROR, // arguments not mapped to parameters (i.e. different size of arguments and parameters)
INAPPLICABLE, // arguments have wrong types INAPPLICABLE, // arguments have wrong types
INAPPLICABLE_MODIFIER, // no expected modifier (eg infix call on non-infix function) INAPPLICABLE_MODIFIER, // no expected modifier (eg infix call on non-infix function)
NO_COMPANION_OBJECT, // Classifier does not have a companion object
IMPOSSIBLE_TO_GENERATE, // access to outer class from nested IMPOSSIBLE_TO_GENERATE, // access to outer class from nested
RUNTIME_ERROR, // problems with visibility RUNTIME_ERROR, // problems with visibility
UNSAFE_CALL, // receiver or argument nullability doesn't match UNSAFE_CALL, // receiver or argument nullability doesn't match
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
package test package test
import test.C.E1 import test.C.E1
@@ -17,7 +16,6 @@ class A {
} }
fun test() { fun test() {
// Note: FIR resolve this to test/C instead of test/A.B.C
C C
D() D()
} }
@@ -0,0 +1,24 @@
// FIR_IDENTICAL
// https://youtrack.jetbrains.com/issue/KT-48157
import TestEnum.*
enum class TestEnum {
Annotation,
Collection,
Set,
List,
Map,
Function,
Enum
}
fun test() {
val x1 = Annotation
val x2 = Collection
val x3 = Set
val x4 = List
val x5 = Map
val x6 = Function
val x7 = Enum
}
@@ -0,0 +1,34 @@
package
public fun test(): kotlin.Unit
public final enum class TestEnum : kotlin.Enum<TestEnum> {
enum entry Annotation
enum entry Collection
enum entry Set
enum entry List
enum entry Map
enum entry Function
enum entry Enum
private constructor TestEnum()
public final override /*1*/ /*fake_override*/ val name: kotlin.String
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: TestEnum): kotlin.Int
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<TestEnum!>!
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): TestEnum
public final /*synthesized*/ fun values(): kotlin.Array<TestEnum>
}
@@ -24129,6 +24129,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/resolve/resolveAnnotatedLambdaArgument.kt"); runTest("compiler/testData/diagnostics/tests/resolve/resolveAnnotatedLambdaArgument.kt");
} }
@Test
@TestMetadata("resolveToStarImportMemberInsteadOfBuiltin.kt")
public void testResolveToStarImportMemberInsteadOfBuiltin() throws Exception {
runTest("compiler/testData/diagnostics/tests/resolve/resolveToStarImportMemberInsteadOfBuiltin.kt");
}
@Test @Test
@TestMetadata("resolveTypeArgsForUnresolvedCall.kt") @TestMetadata("resolveTypeArgsForUnresolvedCall.kt")
public void testResolveTypeArgsForUnresolvedCall() throws Exception { public void testResolveTypeArgsForUnresolvedCall() throws Exception {
@@ -24117,6 +24117,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
runTest("compiler/testData/diagnostics/tests/resolve/resolveAnnotatedLambdaArgument.kt"); runTest("compiler/testData/diagnostics/tests/resolve/resolveAnnotatedLambdaArgument.kt");
} }
@Test
@TestMetadata("resolveToStarImportMemberInsteadOfBuiltin.kt")
public void testResolveToStarImportMemberInsteadOfBuiltin() throws Exception {
runTest("compiler/testData/diagnostics/tests/resolve/resolveToStarImportMemberInsteadOfBuiltin.kt");
}
@Test @Test
@TestMetadata("resolveTypeArgsForUnresolvedCall.kt") @TestMetadata("resolveTypeArgsForUnresolvedCall.kt")
public void testResolveTypeArgsForUnresolvedCall() throws Exception { public void testResolveTypeArgsForUnresolvedCall() throws Exception {
@@ -1,2 +1,2 @@
Resolved to: Resolved to:
0: (in <local>: test) class Conflict 0: (in test.Conflict) companion object
@@ -1,2 +1,2 @@
Resolved to: Resolved to:
0: (in <local>: test) class Conflict 0: (in test) object Conflict