K2: use intersection scope override checker also in intersection scope
In more details, we use either platform override checker (if we came from platform) or the combined intersection scope override checker at this place. Also this commit fixes various places around JavaOverrideChecker, allowing to apply it in intersection override checker properly: - don't consider return types in this place - apply JavaOverrideChecker if at least one candidate is from Java - compare type primitivity closer to K1 logic #KT-62554 Fixed Partially fixes KT-63242
This commit is contained in:
committed by
Space Team
parent
54d978ba86
commit
e42c1be354
+1
@@ -58,6 +58,7 @@ class JavaClassUseSiteMemberScope(
|
|||||||
klass.symbol.toLookupTag(),
|
klass.symbol.toLookupTag(),
|
||||||
session,
|
session,
|
||||||
JavaOverrideChecker(session, klass.javaTypeParameterStack, superTypeScopes, considerReturnTypeKinds = true),
|
JavaOverrideChecker(session, klass.javaTypeParameterStack, superTypeScopes, considerReturnTypeKinds = true),
|
||||||
|
overrideCheckerForIntersection = null,
|
||||||
superTypeScopes,
|
superTypeScopes,
|
||||||
klass.defaultType(),
|
klass.defaultType(),
|
||||||
declaredMemberScope
|
declaredMemberScope
|
||||||
|
|||||||
+26
-8
@@ -15,20 +15,38 @@ import org.jetbrains.kotlin.fir.scopes.PlatformSpecificOverridabilityRules
|
|||||||
import org.jetbrains.kotlin.fir.unwrapFakeOverrides
|
import org.jetbrains.kotlin.fir.unwrapFakeOverrides
|
||||||
|
|
||||||
class JavaOverridabilityRules(session: FirSession) : PlatformSpecificOverridabilityRules {
|
class JavaOverridabilityRules(session: FirSession) : PlatformSpecificOverridabilityRules {
|
||||||
|
// Note: return types (considerReturnTypeKinds) look not important when attempting intersection
|
||||||
|
// From the other side, they can break relevant tests like intersectionWithJavaVoidNothing.kt
|
||||||
|
// The similar case exists in bootstrap (see IrSimpleBuiltinOperatorDescriptorImpl)
|
||||||
private val javaOverrideChecker =
|
private val javaOverrideChecker =
|
||||||
JavaOverrideChecker(session, JavaTypeParameterStack.EMPTY, baseScopes = null, considerReturnTypeKinds = true)
|
JavaOverrideChecker(session, JavaTypeParameterStack.EMPTY, baseScopes = null, considerReturnTypeKinds = false)
|
||||||
|
|
||||||
override fun isOverriddenFunction(overrideCandidate: FirSimpleFunction, baseDeclaration: FirSimpleFunction): Boolean? {
|
override fun isOverriddenFunction(overrideCandidate: FirSimpleFunction, baseDeclaration: FirSimpleFunction): Boolean? {
|
||||||
if (!overrideCandidate.isFromJava() || !baseDeclaration.isFromJava()) return null
|
return if (shouldApplyJavaChecker(overrideCandidate, baseDeclaration)) {
|
||||||
|
// takeIf is questionable here (JavaOverrideChecker can forbid overriding, but it cannot allow it on own behalf)
|
||||||
return javaOverrideChecker.isOverriddenFunction(overrideCandidate, baseDeclaration)
|
// Known influenced tests: supertypeDifferentParameterNullability.kt became partially green without it
|
||||||
|
javaOverrideChecker.isOverriddenFunction(overrideCandidate, baseDeclaration).takeIf { !it }
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isOverriddenProperty(overrideCandidate: FirCallableDeclaration, baseDeclaration: FirProperty): Boolean? {
|
override fun isOverriddenProperty(overrideCandidate: FirCallableDeclaration, baseDeclaration: FirProperty): Boolean? {
|
||||||
if (!overrideCandidate.isFromJava() || !baseDeclaration.isFromJava()) return null
|
return if (shouldApplyJavaChecker(overrideCandidate, baseDeclaration)) {
|
||||||
|
javaOverrideChecker.isOverriddenProperty(overrideCandidate, baseDeclaration)
|
||||||
return javaOverrideChecker.isOverriddenProperty(overrideCandidate, baseDeclaration)
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirCallableDeclaration.isFromJava(): Boolean = unwrapFakeOverrides().origin == FirDeclarationOrigin.Enhancement
|
private fun shouldApplyJavaChecker(overrideCandidate: FirCallableDeclaration, baseDeclaration: FirCallableDeclaration): Boolean {
|
||||||
|
return when {
|
||||||
|
// One candidate with Java original is enough to apply Java checker,
|
||||||
|
// otherwise e.g. primitive type comparisons do not work
|
||||||
|
overrideCandidate.isOriginallyFromJava() || baseDeclaration.isOriginallyFromJava() -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirCallableDeclaration.isOriginallyFromJava(): Boolean = unwrapFakeOverrides().origin == FirDeclarationOrigin.Enhancement
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.fir.scopes.jvm.computeJvmDescriptorRepresentation
|
|||||||
import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions
|
import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions
|
||||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
import org.jetbrains.kotlin.fir.unwrapFakeOverrides
|
||||||
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
|
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||||
@@ -80,6 +81,7 @@ class JavaOverrideChecker internal constructor(
|
|||||||
substitutor: ConeSubstitutor,
|
substitutor: ConeSubstitutor,
|
||||||
forceBoxCandidateType: Boolean,
|
forceBoxCandidateType: Boolean,
|
||||||
forceBoxBaseType: Boolean,
|
forceBoxBaseType: Boolean,
|
||||||
|
dontComparePrimitivity: Boolean,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val candidateType = candidateTypeRef.toConeKotlinTypeProbablyFlexible(session, javaTypeParameterStack)
|
val candidateType = candidateTypeRef.toConeKotlinTypeProbablyFlexible(session, javaTypeParameterStack)
|
||||||
val baseType = baseTypeRef.toConeKotlinTypeProbablyFlexible(session, javaTypeParameterStack)
|
val baseType = baseTypeRef.toConeKotlinTypeProbablyFlexible(session, javaTypeParameterStack)
|
||||||
@@ -87,7 +89,8 @@ class JavaOverrideChecker internal constructor(
|
|||||||
val candidateTypeIsPrimitive = !forceBoxCandidateType && candidateType.isPrimitiveInJava(isReturnType = false)
|
val candidateTypeIsPrimitive = !forceBoxCandidateType && candidateType.isPrimitiveInJava(isReturnType = false)
|
||||||
val baseTypeIsPrimitive = !forceBoxBaseType && baseType.isPrimitiveInJava(isReturnType = false)
|
val baseTypeIsPrimitive = !forceBoxBaseType && baseType.isPrimitiveInJava(isReturnType = false)
|
||||||
|
|
||||||
return candidateTypeIsPrimitive == baseTypeIsPrimitive && isEqualTypes(candidateType, baseType, substitutor)
|
return (dontComparePrimitivity || candidateTypeIsPrimitive == baseTypeIsPrimitive) &&
|
||||||
|
isEqualTypes(candidateType, baseType, substitutor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// In most cases checking erasure of value parameters should be enough, but in some cases there might be semi-valid Java hierarchies
|
// In most cases checking erasure of value parameters should be enough, but in some cases there might be semi-valid Java hierarchies
|
||||||
@@ -234,19 +237,7 @@ class JavaOverrideChecker internal constructor(
|
|||||||
overrideCandidate.lazyResolveToPhase(FirResolvePhase.TYPES)
|
overrideCandidate.lazyResolveToPhase(FirResolvePhase.TYPES)
|
||||||
baseDeclaration.lazyResolveToPhase(FirResolvePhase.TYPES)
|
baseDeclaration.lazyResolveToPhase(FirResolvePhase.TYPES)
|
||||||
|
|
||||||
// NB: overrideCandidate is from Java and has no receiver
|
if (!overrideCandidate.hasSameValueParameterTypes(baseDeclaration)) {
|
||||||
val receiverTypeRef = baseDeclaration.receiverParameter?.typeRef
|
|
||||||
val baseParameterTypes = listOfNotNull(receiverTypeRef) + baseDeclaration.valueParameters.map { it.returnTypeRef }
|
|
||||||
|
|
||||||
if (overrideCandidate.valueParameters.size != baseParameterTypes.size) return false
|
|
||||||
val substitutor = buildTypeParametersSubstitutorIfCompatible(overrideCandidate, baseDeclaration)
|
|
||||||
|
|
||||||
val forceBoxOverrideParameterType = forceSingleValueParameterBoxing(overrideCandidate)
|
|
||||||
val forceBoxBaseParameterType = forceSingleValueParameterBoxing(baseDeclaration)
|
|
||||||
|
|
||||||
if (!overrideCandidate.valueParameters.zip(baseParameterTypes).all { (paramFromJava, baseType) ->
|
|
||||||
isEqualTypes(paramFromJava.returnTypeRef, baseType, substitutor, forceBoxOverrideParameterType, forceBoxBaseParameterType)
|
|
||||||
}) {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,6 +257,43 @@ class JavaOverrideChecker internal constructor(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun FirSimpleFunction.hasSameValueParameterTypes(other: FirSimpleFunction): Boolean {
|
||||||
|
// NB: 'this' is counted as a Java method that cannot have a receiver
|
||||||
|
val otherValueParameterTypes = other.collectValueParameterTypes()
|
||||||
|
val valueParameterTypes = valueParameters.map { it.returnTypeRef }
|
||||||
|
if (valueParameterTypes.size != otherValueParameterTypes.size) return false
|
||||||
|
|
||||||
|
val substitutor = buildTypeParametersSubstitutorIfCompatible(this, other)
|
||||||
|
val forceBoxValueParameterType = forceSingleValueParameterBoxing(this)
|
||||||
|
val forceBoxOtherValueParameterType = forceSingleValueParameterBoxing(other)
|
||||||
|
val otherUnwrappedValueParameterTypes = other.unwrapFakeOverrides().collectValueParameterTypes()
|
||||||
|
val unwrappedValueParameterTypes = unwrapFakeOverrides().valueParameters.map { it.returnTypeRef }
|
||||||
|
|
||||||
|
for (i in valueParameterTypes.indices) {
|
||||||
|
if (!isEqualTypes(
|
||||||
|
candidateTypeRef = valueParameterTypes[i],
|
||||||
|
baseTypeRef = otherValueParameterTypes[i],
|
||||||
|
substitutor = substitutor,
|
||||||
|
forceBoxCandidateType = forceBoxValueParameterType,
|
||||||
|
forceBoxBaseType = forceBoxOtherValueParameterType,
|
||||||
|
// This very hacky place is needed to match K1 logic
|
||||||
|
// See triangleWithFlexibleTypeAndSubstitution4.kt and neighbor tests
|
||||||
|
// The idea: normally in Java primitive type does not match non-primitive one
|
||||||
|
// However, if *both* types were constructed as generic substitutions,
|
||||||
|
// this check can (and should) be omitted
|
||||||
|
dontComparePrimitivity = otherUnwrappedValueParameterTypes.getOrNull(i)?.isTypeParameterDependent() == true &&
|
||||||
|
unwrappedValueParameterTypes.getOrNull(i)?.isTypeParameterDependent() == true,
|
||||||
|
)
|
||||||
|
) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirSimpleFunction.collectValueParameterTypes(): List<FirTypeRef> {
|
||||||
|
val receiverTypeRef = receiverParameter?.typeRef
|
||||||
|
return listOfNotNull(receiverTypeRef) + valueParameters.map { it.returnTypeRef }
|
||||||
|
}
|
||||||
|
|
||||||
override fun isOverriddenProperty(overrideCandidate: FirCallableDeclaration, baseDeclaration: FirProperty): Boolean {
|
override fun isOverriddenProperty(overrideCandidate: FirCallableDeclaration, baseDeclaration: FirProperty): Boolean {
|
||||||
if (baseDeclaration.modality == Modality.FINAL) return false
|
if (baseDeclaration.modality == Modality.FINAL) return false
|
||||||
|
|
||||||
@@ -282,7 +310,8 @@ class JavaOverrideChecker internal constructor(
|
|||||||
if (overrideCandidate.valueParameters.size != 1) return false
|
if (overrideCandidate.valueParameters.size != 1) return false
|
||||||
return isEqualTypes(
|
return isEqualTypes(
|
||||||
receiverTypeRef, overrideCandidate.valueParameters.single().returnTypeRef, ConeSubstitutor.Empty,
|
receiverTypeRef, overrideCandidate.valueParameters.single().returnTypeRef, ConeSubstitutor.Empty,
|
||||||
forceBoxCandidateType = false, forceBoxBaseType = false
|
forceBoxCandidateType = false, forceBoxBaseType = false,
|
||||||
|
dontComparePrimitivity = false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -293,7 +322,8 @@ class JavaOverrideChecker internal constructor(
|
|||||||
overrideReceiverTypeRef == null -> false
|
overrideReceiverTypeRef == null -> false
|
||||||
else -> isEqualTypes(
|
else -> isEqualTypes(
|
||||||
receiverTypeRef, overrideReceiverTypeRef, ConeSubstitutor.Empty,
|
receiverTypeRef, overrideReceiverTypeRef, ConeSubstitutor.Empty,
|
||||||
forceBoxCandidateType = false, forceBoxBaseType = false
|
forceBoxCandidateType = false, forceBoxBaseType = false,
|
||||||
|
dontComparePrimitivity = false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-4
@@ -18,13 +18,18 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
abstract class AbstractFirUseSiteMemberScope(
|
abstract class AbstractFirUseSiteMemberScope(
|
||||||
val ownerClassLookupTag: ConeClassLikeLookupTag,
|
val ownerClassLookupTag: ConeClassLikeLookupTag,
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
overrideChecker: FirOverrideChecker,
|
overrideCheckerForBaseClass: FirOverrideChecker,
|
||||||
|
// null means "use overrideCheckerForBaseClass"
|
||||||
|
overrideCheckerForIntersection: FirOverrideChecker?,
|
||||||
protected val superTypeScopes: List<FirTypeScope>,
|
protected val superTypeScopes: List<FirTypeScope>,
|
||||||
dispatchReceiverType: ConeSimpleKotlinType,
|
dispatchReceiverType: ConeSimpleKotlinType,
|
||||||
protected val declaredMemberScope: FirContainingNamesAwareScope
|
protected val declaredMemberScope: FirContainingNamesAwareScope
|
||||||
) : AbstractFirOverrideScope(session, overrideChecker) {
|
) : AbstractFirOverrideScope(session, overrideCheckerForBaseClass) {
|
||||||
protected val supertypeScopeContext =
|
protected val supertypeScopeContext = FirTypeIntersectionScopeContext(
|
||||||
FirTypeIntersectionScopeContext(session, overrideChecker, superTypeScopes, dispatchReceiverType, forClassUseSiteScope = true)
|
session,
|
||||||
|
overrideCheckerForIntersection ?: overrideCheckerForBaseClass,
|
||||||
|
superTypeScopes, dispatchReceiverType, forClassUseSiteScope = true
|
||||||
|
)
|
||||||
|
|
||||||
private val functions: MutableMap<Name, Collection<FirNamedFunctionSymbol>> = hashMapOf()
|
private val functions: MutableMap<Name, Collection<FirNamedFunctionSymbol>> = hashMapOf()
|
||||||
|
|
||||||
|
|||||||
+6
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.declarations.FirClass
|
|||||||
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
|
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
|
||||||
import org.jetbrains.kotlin.fir.resolve.defaultType
|
import org.jetbrains.kotlin.fir.resolve.defaultType
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
|
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.FirIntersectionScopeOverrideChecker
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.firOverrideChecker
|
import org.jetbrains.kotlin.fir.scopes.firOverrideChecker
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
@@ -24,6 +25,11 @@ class FirClassUseSiteMemberScope(
|
|||||||
klass.symbol.toLookupTag(),
|
klass.symbol.toLookupTag(),
|
||||||
session,
|
session,
|
||||||
session.firOverrideChecker,
|
session.firOverrideChecker,
|
||||||
|
// The checker here is used for matching supertype intersections
|
||||||
|
// If we came here from platform (e.g. Native), we use a platform override checker
|
||||||
|
// JavaClassUseSiteMemberScope also uses its own JavaOverrideChecker here
|
||||||
|
// Otherwise we should use a special intersection checker (similar one is used in FirTypeIntersectionScope)
|
||||||
|
session.firOverrideChecker.takeIf { it !is FirStandardOverrideChecker } ?: FirIntersectionScopeOverrideChecker(session),
|
||||||
superTypeScopes,
|
superTypeScopes,
|
||||||
klass.defaultType(),
|
klass.defaultType(),
|
||||||
declaredMemberScope
|
declaredMemberScope
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// TARGET_BACKEND: JVM_IR
|
// TARGET_BACKEND: JVM_IR
|
||||||
// IGNORE_BACKEND_K2: JVM_IR
|
|
||||||
// IGNORE_LIGHT_ANALYSIS
|
// IGNORE_LIGHT_ANALYSIS
|
||||||
// (Unresolved reference: B supertype in C declaration)
|
// (Unresolved reference: B supertype in C declaration)
|
||||||
// ISSUE: KT-63242
|
// ISSUE: KT-63242
|
||||||
|
|||||||
-20
@@ -1,20 +0,0 @@
|
|||||||
// ISSUE: KT-62554
|
|
||||||
// FIR_DUMP
|
|
||||||
// SCOPE_DUMP: C:foo
|
|
||||||
// FILE: A.java
|
|
||||||
|
|
||||||
public class A {
|
|
||||||
public void foo(Integer x) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FILE: main.kt
|
|
||||||
|
|
||||||
interface B {
|
|
||||||
fun foo(x: Int) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class C<!> : A(), B
|
|
||||||
|
|
||||||
fun main() {
|
|
||||||
C().foo(42)
|
|
||||||
}
|
|
||||||
-4
@@ -1,4 +0,0 @@
|
|||||||
C:
|
|
||||||
[IntersectionOverride]: public open fun foo(x: R|kotlin/Int!|): R|kotlin/Unit| from Use site scope of /C [id: 0]
|
|
||||||
[Enhancement]: public open fun foo(x: R|kotlin/Int!|): R|kotlin/Unit| from Java enhancement scope for /A [id: 1]
|
|
||||||
[Source]: public open fun foo(x: R|kotlin/Int|): R|kotlin/Unit| from Use site scope of /B [id: 2]
|
|
||||||
Vendored
+1
-1
@@ -11,5 +11,5 @@ FILE: main.kt
|
|||||||
|
|
||||||
}
|
}
|
||||||
public final fun main(): R|kotlin/Unit| {
|
public final fun main(): R|kotlin/Unit| {
|
||||||
R|/C.C|().R|/A.foo|(Int(42))
|
R|/C.C|().R|/B.foo|(Int(42))
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// ISSUE: KT-62554
|
// ISSUE: KT-62554
|
||||||
// FIR_DUMP
|
// FIR_DUMP
|
||||||
// SCOPE_DUMP: C:foo
|
// SCOPE_DUMP: C:foo
|
||||||
|
|||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
C:
|
||||||
|
[Enhancement]: public open fun foo(x: R|kotlin/Int!|): R|kotlin/Unit| from Use site scope of /C [id: 0]
|
||||||
|
[Enhancement]: public open fun foo(x: R|kotlin/Int!|): R|kotlin/Unit| from Java enhancement scope for /A [id: 0]
|
||||||
|
[Source]: public open fun foo(x: R|kotlin/Int|): R|kotlin/Unit| from Use site scope of /C [id: 0]
|
||||||
|
[Source]: public open fun foo(x: R|kotlin/Int|): R|kotlin/Unit| from Use site scope of /B [id: 0]
|
||||||
|
|
||||||
-24
@@ -1,24 +0,0 @@
|
|||||||
// ISSUE: KT-62554
|
|
||||||
// FIR_DUMP
|
|
||||||
// SCOPE_DUMP: D:foo
|
|
||||||
// FILE: A.java
|
|
||||||
|
|
||||||
public class A<T> {
|
|
||||||
public T foo(Integer x) {
|
|
||||||
return "A";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FILE: main.kt
|
|
||||||
|
|
||||||
interface B {
|
|
||||||
fun foo(x: Int) = "B"
|
|
||||||
}
|
|
||||||
|
|
||||||
open class C : A<String>()
|
|
||||||
|
|
||||||
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class D<!> : C(), B
|
|
||||||
|
|
||||||
fun main() {
|
|
||||||
D().foo(42)
|
|
||||||
}
|
|
||||||
-6
@@ -1,6 +0,0 @@
|
|||||||
D:
|
|
||||||
[IntersectionOverride]: public open fun foo(x: R|kotlin/Int|): R|kotlin/String| from Use site scope of /D [id: 0]
|
|
||||||
[SubstitutionOverride(DeclarationSite)]: public open fun foo(x: R|kotlin/Int!|): R|kotlin/String!| from Use site scope of /C [id: 1]
|
|
||||||
[SubstitutionOverride(DeclarationSite)]: public open fun foo(x: R|kotlin/Int!|): R|kotlin/String!| from Substitution scope for [Java enhancement scope for /A] for type C [id: 1]
|
|
||||||
[Enhancement]: public open fun foo(x: R|kotlin/Int!|): R|ft<T & Any, T?>| from Java enhancement scope for /A [id: 2]
|
|
||||||
[Source]: public open fun foo(x: R|kotlin/Int|): R|kotlin/String| from Use site scope of /B [id: 3]
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// ISSUE: KT-62554
|
// ISSUE: KT-62554
|
||||||
// FIR_DUMP
|
// FIR_DUMP
|
||||||
// SCOPE_DUMP: D:foo
|
// SCOPE_DUMP: D:foo
|
||||||
|
|||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
D:
|
||||||
|
[SubstitutionOverride(DeclarationSite)]: public open fun foo(x: R|kotlin/Int!|): R|kotlin/String!| from Use site scope of /D [id: 0]
|
||||||
|
[SubstitutionOverride(DeclarationSite)]: public open fun foo(x: R|kotlin/Int!|): R|kotlin/String!| from Use site scope of /C [id: 0]
|
||||||
|
[SubstitutionOverride(DeclarationSite)]: public open fun foo(x: R|kotlin/Int!|): R|kotlin/String!| from Substitution scope for [Java enhancement scope for /A] for type C [id: 0]
|
||||||
|
[Enhancement]: public open fun foo(x: R|kotlin/Int!|): R|ft<T & Any, T?>| from Java enhancement scope for /A [id: 1]
|
||||||
|
[Source]: public open fun foo(x: R|kotlin/Int|): R|kotlin/String| from Use site scope of /D [id: 0]
|
||||||
|
[Source]: public open fun foo(x: R|kotlin/Int|): R|kotlin/String| from Use site scope of /B [id: 0]
|
||||||
-26
@@ -1,26 +0,0 @@
|
|||||||
// ISSUE: KT-62554
|
|
||||||
// FIR_DUMP
|
|
||||||
// SCOPE_DUMP: D:foo
|
|
||||||
// FILE: A.java
|
|
||||||
|
|
||||||
public class A<T> {
|
|
||||||
public String foo(T x) {
|
|
||||||
return "A";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FILE: C.java
|
|
||||||
|
|
||||||
public class C extends A<Integer> {}
|
|
||||||
|
|
||||||
// FILE: main.kt
|
|
||||||
|
|
||||||
interface B {
|
|
||||||
fun foo(x: Int) = "B"
|
|
||||||
}
|
|
||||||
|
|
||||||
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class D<!> : C(), B
|
|
||||||
|
|
||||||
fun main() {
|
|
||||||
D().foo(42)
|
|
||||||
}
|
|
||||||
-6
@@ -1,6 +0,0 @@
|
|||||||
D:
|
|
||||||
[IntersectionOverride]: public open fun foo(x: R|kotlin/Int|): R|kotlin/String| from Use site scope of /D [id: 0]
|
|
||||||
[SubstitutionOverride(DeclarationSite)]: public open fun foo(x: R|kotlin/Int!|): R|kotlin/String!| from Java enhancement scope for /C [id: 1]
|
|
||||||
[SubstitutionOverride(DeclarationSite)]: public open fun foo(x: R|kotlin/Int!|): R|kotlin/String!| from Substitution scope for [Java enhancement scope for /A] for type C [id: 1]
|
|
||||||
[Enhancement]: public open fun foo(x: R|ft<T & Any, T?>|): R|kotlin/String!| from Java enhancement scope for /A [id: 2]
|
|
||||||
[Source]: public open fun foo(x: R|kotlin/Int|): R|kotlin/String| from Use site scope of /B [id: 3]
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// ISSUE: KT-62554
|
// ISSUE: KT-62554
|
||||||
// FIR_DUMP
|
// FIR_DUMP
|
||||||
// SCOPE_DUMP: D:foo
|
// SCOPE_DUMP: D:foo
|
||||||
|
|||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
D:
|
||||||
|
[SubstitutionOverride(DeclarationSite)]: public open fun foo(x: R|kotlin/Int!|): R|kotlin/String!| from Use site scope of /D [id: 0]
|
||||||
|
[SubstitutionOverride(DeclarationSite)]: public open fun foo(x: R|kotlin/Int!|): R|kotlin/String!| from Java enhancement scope for /C [id: 0]
|
||||||
|
[SubstitutionOverride(DeclarationSite)]: public open fun foo(x: R|kotlin/Int!|): R|kotlin/String!| from Substitution scope for [Java enhancement scope for /A] for type C [id: 0]
|
||||||
|
[Enhancement]: public open fun foo(x: R|ft<T & Any, T?>|): R|kotlin/String!| from Java enhancement scope for /A [id: 1]
|
||||||
|
[Source]: public open fun foo(x: R|kotlin/Int|): R|kotlin/String| from Use site scope of /D [id: 0]
|
||||||
|
[Source]: public open fun foo(x: R|kotlin/Int|): R|kotlin/String| from Use site scope of /B [id: 0]
|
||||||
-24
@@ -1,24 +0,0 @@
|
|||||||
// ISSUE: KT-62554
|
|
||||||
// FIR_DUMP
|
|
||||||
// SCOPE_DUMP: D:foo
|
|
||||||
// FILE: A.java
|
|
||||||
|
|
||||||
public class A<T> {
|
|
||||||
public String foo(T x) {
|
|
||||||
return "A";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FILE: main.kt
|
|
||||||
|
|
||||||
interface B {
|
|
||||||
fun foo(x: Int) = "B"
|
|
||||||
}
|
|
||||||
|
|
||||||
open class C : A<Int>()
|
|
||||||
|
|
||||||
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class D<!> : C(), B
|
|
||||||
|
|
||||||
fun main() {
|
|
||||||
D().foo(42)
|
|
||||||
}
|
|
||||||
-6
@@ -1,6 +0,0 @@
|
|||||||
D:
|
|
||||||
[IntersectionOverride]: public open fun foo(x: R|kotlin/Int|): R|kotlin/String| from Use site scope of /D [id: 0]
|
|
||||||
[SubstitutionOverride(DeclarationSite)]: public open fun foo(x: R|kotlin/Int!|): R|kotlin/String!| from Use site scope of /C [id: 1]
|
|
||||||
[SubstitutionOverride(DeclarationSite)]: public open fun foo(x: R|kotlin/Int!|): R|kotlin/String!| from Substitution scope for [Java enhancement scope for /A] for type C [id: 1]
|
|
||||||
[Enhancement]: public open fun foo(x: R|ft<T & Any, T?>|): R|kotlin/String!| from Java enhancement scope for /A [id: 2]
|
|
||||||
[Source]: public open fun foo(x: R|kotlin/Int|): R|kotlin/String| from Use site scope of /B [id: 3]
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// ISSUE: KT-62554
|
// ISSUE: KT-62554
|
||||||
// FIR_DUMP
|
// FIR_DUMP
|
||||||
// SCOPE_DUMP: D:foo
|
// SCOPE_DUMP: D:foo
|
||||||
|
|||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
D:
|
||||||
|
[SubstitutionOverride(DeclarationSite)]: public open fun foo(x: R|kotlin/Int!|): R|kotlin/String!| from Use site scope of /D [id: 0]
|
||||||
|
[SubstitutionOverride(DeclarationSite)]: public open fun foo(x: R|kotlin/Int!|): R|kotlin/String!| from Use site scope of /C [id: 0]
|
||||||
|
[SubstitutionOverride(DeclarationSite)]: public open fun foo(x: R|kotlin/Int!|): R|kotlin/String!| from Substitution scope for [Java enhancement scope for /A] for type C [id: 0]
|
||||||
|
[Enhancement]: public open fun foo(x: R|ft<T & Any, T?>|): R|kotlin/String!| from Java enhancement scope for /A [id: 1]
|
||||||
|
[Source]: public open fun foo(x: R|kotlin/Int|): R|kotlin/String| from Use site scope of /D [id: 0]
|
||||||
|
[Source]: public open fun foo(x: R|kotlin/Int|): R|kotlin/String| from Use site scope of /B [id: 0]
|
||||||
+2
@@ -1,6 +1,8 @@
|
|||||||
// ISSUE: KT-62554
|
// ISSUE: KT-62554
|
||||||
// FIR_DUMP
|
// FIR_DUMP
|
||||||
// SCOPE_DUMP: E:foo
|
// SCOPE_DUMP: E:foo
|
||||||
|
// IGNORE_REVERSED_RESOLVE
|
||||||
|
// ^ resolves to C.foo instead of D.foo for some reason, does not seem important
|
||||||
// FILE: A.java
|
// FILE: A.java
|
||||||
|
|
||||||
public class A<T> {
|
public class A<T> {
|
||||||
|
|||||||
+2
@@ -1,6 +1,8 @@
|
|||||||
// ISSUE: KT-62554
|
// ISSUE: KT-62554
|
||||||
// FIR_DUMP
|
// FIR_DUMP
|
||||||
// SCOPE_DUMP: E:foo
|
// SCOPE_DUMP: E:foo
|
||||||
|
// IGNORE_REVERSED_RESOLVE
|
||||||
|
// ^ resolves to C.foo instead of D.foo for some reason, does not seem important
|
||||||
// FILE: A.java
|
// FILE: A.java
|
||||||
|
|
||||||
public class A<T> {
|
public class A<T> {
|
||||||
|
|||||||
-24
@@ -1,24 +0,0 @@
|
|||||||
// ISSUE: KT-62554
|
|
||||||
// FIR_DUMP
|
|
||||||
// SCOPE_DUMP: E:foo
|
|
||||||
// FILE: A.java
|
|
||||||
|
|
||||||
public class A {
|
|
||||||
public String foo(Integer x) {
|
|
||||||
return "A";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FILE: main.kt
|
|
||||||
|
|
||||||
interface B<T> {
|
|
||||||
fun foo(x: T) = "B"
|
|
||||||
}
|
|
||||||
|
|
||||||
interface D : B<Int>
|
|
||||||
|
|
||||||
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class E<!> : A(), D
|
|
||||||
|
|
||||||
fun main() {
|
|
||||||
E().foo(42)
|
|
||||||
}
|
|
||||||
+1
-1
@@ -14,5 +14,5 @@ FILE: main.kt
|
|||||||
|
|
||||||
}
|
}
|
||||||
public final fun main(): R|kotlin/Unit| {
|
public final fun main(): R|kotlin/Unit| {
|
||||||
R|/E.E|().R|/D.foo|(Int(42))
|
R|/E.E|().R|SubstitutionOverride</D.foo: R|kotlin/String|>|(Int(42))
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// ISSUE: KT-62554
|
// ISSUE: KT-62554
|
||||||
// FIR_DUMP
|
// FIR_DUMP
|
||||||
// SCOPE_DUMP: E:foo
|
// SCOPE_DUMP: E:foo
|
||||||
|
|||||||
+6
-5
@@ -1,6 +1,7 @@
|
|||||||
E:
|
E:
|
||||||
[IntersectionOverride]: public open fun foo(x: R|kotlin/Int|): R|kotlin/String| from Use site scope of /E [id: 0]
|
[Enhancement]: public open fun foo(x: R|kotlin/Int!|): R|kotlin/String!| from Use site scope of /E [id: 0]
|
||||||
[Enhancement]: public open fun foo(x: R|kotlin/Int!|): R|kotlin/String!| from Java enhancement scope for /A [id: 1]
|
[Enhancement]: public open fun foo(x: R|kotlin/Int!|): R|kotlin/String!| from Java enhancement scope for /A [id: 0]
|
||||||
[SubstitutionOverride(DeclarationSite)]: public open fun foo(x: R|kotlin/Int|): R|kotlin/String| from Use site scope of /D [id: 2]
|
[SubstitutionOverride(DeclarationSite)]: public open fun foo(x: R|kotlin/Int|): R|kotlin/String| from Use site scope of /E [id: 0]
|
||||||
[SubstitutionOverride(DeclarationSite)]: public open fun foo(x: R|kotlin/Int|): R|kotlin/String| from Substitution scope for [Use site scope of /B] for type D [id: 2]
|
[SubstitutionOverride(DeclarationSite)]: public open fun foo(x: R|kotlin/Int|): R|kotlin/String| from Use site scope of /D [id: 0]
|
||||||
[Source]: public open fun foo(x: R|T|): R|kotlin/String| from Use site scope of /B [id: 3]
|
[SubstitutionOverride(DeclarationSite)]: public open fun foo(x: R|kotlin/Int|): R|kotlin/String| from Substitution scope for [Use site scope of /B] for type D [id: 0]
|
||||||
|
[Source]: public open fun foo(x: R|T|): R|kotlin/String| from Use site scope of /B [id: 1]
|
||||||
-22
@@ -1,22 +0,0 @@
|
|||||||
// ISSUE: KT-62554
|
|
||||||
// FIR_DUMP
|
|
||||||
// SCOPE_DUMP: C:foo
|
|
||||||
// FILE: A.java
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.*;
|
|
||||||
|
|
||||||
public class A {
|
|
||||||
public void foo(@NotNull Integer x) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FILE: main.kt
|
|
||||||
|
|
||||||
interface B {
|
|
||||||
fun foo(x: Int) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class C<!> : A(), B
|
|
||||||
|
|
||||||
fun main() {
|
|
||||||
C().foo(42)
|
|
||||||
}
|
|
||||||
compiler/testData/diagnostics/tests/j+k/primitiveOverrides/triangleWithNotNullType.fir.overrides.txt
Vendored
-4
@@ -1,4 +0,0 @@
|
|||||||
C:
|
|
||||||
[IntersectionOverride]: public open fun foo(x: R|@EnhancedNullability kotlin/Int|): R|kotlin/Unit| from Use site scope of /C [id: 0]
|
|
||||||
[Enhancement]: public open fun foo(x: R|@EnhancedNullability kotlin/Int|): R|kotlin/Unit| from Java enhancement scope for /A [id: 1]
|
|
||||||
[Source]: public open fun foo(x: R|kotlin/Int|): R|kotlin/Unit| from Use site scope of /B [id: 2]
|
|
||||||
+1
-1
@@ -11,5 +11,5 @@ FILE: main.kt
|
|||||||
|
|
||||||
}
|
}
|
||||||
public final fun main(): R|kotlin/Unit| {
|
public final fun main(): R|kotlin/Unit| {
|
||||||
R|/C.C|().R|/A.foo|(Int(42))
|
R|/C.C|().<Ambiguity: foo, [/A.foo, /B.foo]>#(Int(42))
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// ISSUE: KT-62554
|
// ISSUE: KT-62554
|
||||||
// FIR_DUMP
|
// FIR_DUMP
|
||||||
// SCOPE_DUMP: C:foo
|
// SCOPE_DUMP: C:foo
|
||||||
|
|||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
C:
|
||||||
|
[Enhancement]: public open fun foo(x: R|@EnhancedNullability kotlin/Int|): R|kotlin/Unit| from Use site scope of /C [id: 0]
|
||||||
|
[Enhancement]: public open fun foo(x: R|@EnhancedNullability kotlin/Int|): R|kotlin/Unit| from Java enhancement scope for /A [id: 0]
|
||||||
|
[Source]: public open fun foo(x: R|kotlin/Int|): R|kotlin/Unit| from Use site scope of /C [id: 0]
|
||||||
|
[Source]: public open fun foo(x: R|kotlin/Int|): R|kotlin/Unit| from Use site scope of /B [id: 0]
|
||||||
|
|
||||||
+1
-1
@@ -8,7 +8,7 @@ interface II {
|
|||||||
fun replace(key: Int, value: Int): Int? = null
|
fun replace(key: Int, value: Int): Int? = null
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract <!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class ZI<!> : MyMap<Int, Int>(), II
|
abstract class ZI : MyMap<Int, Int>(), II
|
||||||
|
|
||||||
interface IS {
|
interface IS {
|
||||||
fun replace(key: String, value: String): String? = null
|
fun replace(key: String, value: String): String? = null
|
||||||
|
|||||||
Reference in New Issue
Block a user