FIR: Fix scope intersection types
Otherwise overload resolution ambiguity is reported in the test
This commit is contained in:
@@ -12,7 +12,10 @@ import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParametersOwner
|
import org.jetbrains.kotlin.fir.declarations.FirTypeParametersOwner
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.*
|
import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerLiteralTypeScope
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.impl.FirStandardOverrideChecker
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.impl.FirSuperTypeScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.scope
|
import org.jetbrains.kotlin.fir.scopes.scope
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||||
@@ -43,7 +46,9 @@ fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: ScopeSession)
|
|||||||
}
|
}
|
||||||
is ConeRawType -> lowerBound.scope(useSiteSession, scopeSession)
|
is ConeRawType -> lowerBound.scope(useSiteSession, scopeSession)
|
||||||
is ConeFlexibleType -> lowerBound.scope(useSiteSession, scopeSession)
|
is ConeFlexibleType -> lowerBound.scope(useSiteSession, scopeSession)
|
||||||
is ConeIntersectionType -> FirCompositeScope(
|
is ConeIntersectionType -> FirSuperTypeScope.prepareSupertypeScope(
|
||||||
|
useSiteSession,
|
||||||
|
FirStandardOverrideChecker(useSiteSession),
|
||||||
intersectedTypes.mapNotNullTo(mutableListOf()) {
|
intersectedTypes.mapNotNullTo(mutableListOf()) {
|
||||||
it.scope(useSiteSession, scopeSession)
|
it.scope(useSiteSession, scopeSession)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
interface A {
|
||||||
|
fun foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class B : A {
|
||||||
|
override fun foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface C : A {}
|
||||||
|
|
||||||
|
fun main(c: C) {
|
||||||
|
if (c !is B) return
|
||||||
|
c.foo()
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
FILE: intersectionScope.kt
|
||||||
|
public abstract interface A : R|kotlin/Any| {
|
||||||
|
public abstract fun foo(): R|kotlin/Unit|
|
||||||
|
|
||||||
|
}
|
||||||
|
public abstract class B : R|A| {
|
||||||
|
public constructor(): R|B| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public open override fun foo(): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public abstract interface C : R|A| {
|
||||||
|
}
|
||||||
|
public final fun main(c: R|C|): R|kotlin/Unit| {
|
||||||
|
when () {
|
||||||
|
(R|<local>/c| !is R|B|) -> {
|
||||||
|
^main Unit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
R|<local>/c|.R|/B.foo|()
|
||||||
|
}
|
||||||
+5
@@ -143,6 +143,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/genericFunctions.kt");
|
runTest("compiler/fir/resolve/testData/resolve/genericFunctions.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("intersectionScope.kt")
|
||||||
|
public void testIntersectionScope() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/intersectionScope.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("intersectionTypes.kt")
|
@TestMetadata("intersectionTypes.kt")
|
||||||
public void testIntersectionTypes() throws Exception {
|
public void testIntersectionTypes() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/intersectionTypes.kt");
|
runTest("compiler/fir/resolve/testData/resolve/intersectionTypes.kt");
|
||||||
|
|||||||
Generated
+5
@@ -143,6 +143,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/genericFunctions.kt");
|
runTest("compiler/fir/resolve/testData/resolve/genericFunctions.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("intersectionScope.kt")
|
||||||
|
public void testIntersectionScope() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/intersectionScope.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("intersectionTypes.kt")
|
@TestMetadata("intersectionTypes.kt")
|
||||||
public void testIntersectionTypes() throws Exception {
|
public void testIntersectionTypes() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/intersectionTypes.kt");
|
runTest("compiler/fir/resolve/testData/resolve/intersectionTypes.kt");
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
public fun box() : String {
|
public fun box() : String {
|
||||||
var i : Short?
|
var i : Short?
|
||||||
i = 10
|
i = 10
|
||||||
|
|||||||
+2
-2
@@ -23,9 +23,9 @@ class WrongIncDec() {
|
|||||||
fun testWrongIncDec() {
|
fun testWrongIncDec() {
|
||||||
var x = WrongIncDec()
|
var x = WrongIncDec()
|
||||||
x++
|
x++
|
||||||
<!AMBIGUITY!>++<!>x
|
++x
|
||||||
x--
|
x--
|
||||||
<!AMBIGUITY!>--<!>x
|
--x
|
||||||
}
|
}
|
||||||
|
|
||||||
class UnitIncDec() {
|
class UnitIncDec() {
|
||||||
|
|||||||
Vendored
+1
-1
@@ -10,7 +10,7 @@ class C() {
|
|||||||
fun test(a : Any?) {
|
fun test(a : Any?) {
|
||||||
if (a is B) {
|
if (a is B) {
|
||||||
if (a is C) {
|
if (a is C) {
|
||||||
a.<!AMBIGUITY!>bar<!>();
|
a.bar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ fun <T : CharSequence?> foo(x: T) {
|
|||||||
x.length
|
x.length
|
||||||
|
|
||||||
if (x is String) {
|
if (x is String) {
|
||||||
x.<!AMBIGUITY!>length<!>
|
x.length
|
||||||
x?.<!AMBIGUITY!>length<!>
|
x?.length
|
||||||
|
|
||||||
x.bar1()
|
x.bar1()
|
||||||
x.bar2()
|
x.bar2()
|
||||||
|
|||||||
Vendored
+1
-1
@@ -31,6 +31,6 @@ import p.*
|
|||||||
|
|
||||||
fun test(b: B<String>?) {
|
fun test(b: B<String>?) {
|
||||||
if (b is C) {
|
if (b is C) {
|
||||||
b?.<!AMBIGUITY!>foo<!>()
|
b?.foo()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -33,6 +33,6 @@ import p.*
|
|||||||
|
|
||||||
fun test(b: B?) {
|
fun test(b: B?) {
|
||||||
if (b is C && b is D) {
|
if (b is C && b is D) {
|
||||||
b?.<!AMBIGUITY!>getParent<!>()
|
b?.getParent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+16
-16
@@ -4,31 +4,31 @@ fun intBinEq() {
|
|||||||
x += 1.toByte()
|
x += 1.toByte()
|
||||||
x += 1.toShort()
|
x += 1.toShort()
|
||||||
x += 1L
|
x += 1L
|
||||||
<!UNRESOLVED_REFERENCE!>x += 1f<!>
|
x += 1f
|
||||||
<!UNRESOLVED_REFERENCE!>x += 1.0<!>
|
x += 1.0
|
||||||
<!UNRESOLVED_REFERENCE!>x *= 'a'<!>
|
<!UNRESOLVED_REFERENCE!>x *= 'a'<!>
|
||||||
<!UNRESOLVED_REFERENCE!>x *= 1.toByte()<!>
|
x *= 1.toByte()
|
||||||
<!UNRESOLVED_REFERENCE!>x *= 1.toShort()<!>
|
x *= 1.toShort()
|
||||||
<!UNRESOLVED_REFERENCE!>x *= 1L<!>
|
x *= 1L
|
||||||
<!UNRESOLVED_REFERENCE!>x *= 1f<!>
|
x *= 1f
|
||||||
<!UNRESOLVED_REFERENCE!>x *= 1.0<!>
|
x *= 1.0
|
||||||
}
|
}
|
||||||
|
|
||||||
fun shortBinEq() {
|
fun shortBinEq() {
|
||||||
var x = 0.toShort()
|
var x = 0.toShort()
|
||||||
<!UNRESOLVED_REFERENCE!>x += 'a'<!>
|
<!UNRESOLVED_REFERENCE!>x += 'a'<!>
|
||||||
x += 1.toByte()
|
x += 1.toByte()
|
||||||
<!UNRESOLVED_REFERENCE!>x += 1.toShort()<!>
|
x += 1.toShort()
|
||||||
<!UNRESOLVED_REFERENCE!>x += 1L<!>
|
x += 1L
|
||||||
<!UNRESOLVED_REFERENCE!>x += 1f<!>
|
x += 1f
|
||||||
<!UNRESOLVED_REFERENCE!>x += 1.0<!>
|
x += 1.0
|
||||||
|
|
||||||
<!UNRESOLVED_REFERENCE!>x *= 'a'<!>
|
<!UNRESOLVED_REFERENCE!>x *= 'a'<!>
|
||||||
<!UNRESOLVED_REFERENCE!>x *= 1.toByte()<!>
|
x *= 1.toByte()
|
||||||
<!UNRESOLVED_REFERENCE!>x *= 1.toShort()<!>
|
x *= 1.toShort()
|
||||||
<!UNRESOLVED_REFERENCE!>x *= 1L<!>
|
x *= 1L
|
||||||
<!UNRESOLVED_REFERENCE!>x *= 1f<!>
|
x *= 1f
|
||||||
<!UNRESOLVED_REFERENCE!>x *= 1.0<!>
|
x *= 1.0
|
||||||
}
|
}
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
|
|||||||
+1
-1
@@ -37,7 +37,7 @@ fun main(
|
|||||||
a.foo(it)
|
a.foo(it)
|
||||||
|
|
||||||
// Iterators
|
// Iterators
|
||||||
a.<!AMBIGUITY!>foo<!>(ml.<!AMBIGUITY!>iterator<!>())
|
a.foo(ml.iterator())
|
||||||
a.foo(l.iterator())
|
a.foo(l.iterator())
|
||||||
|
|
||||||
// Sets
|
// Sets
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ interface IFoo {
|
|||||||
fun test() {
|
fun test() {
|
||||||
val foo : Foo = Foo2()
|
val foo : Foo = Foo2()
|
||||||
foo as IFoo
|
foo as IFoo
|
||||||
foo.<!AMBIGUITY!>bar<!>() // Should be resolved to Foo#bar
|
foo.bar() // Should be resolved to Foo#bar
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IFoo2 {
|
interface IFoo2 {
|
||||||
@@ -24,5 +24,5 @@ interface IFoo2 {
|
|||||||
|
|
||||||
fun test2(foo: Foo) {
|
fun test2(foo: Foo) {
|
||||||
foo as IFoo2
|
foo as IFoo2
|
||||||
foo.<!AMBIGUITY!>bar<!>() // should be ambiguity
|
foo.bar() // should be ambiguity
|
||||||
}
|
}
|
||||||
+1
-1
@@ -12,7 +12,7 @@ class C() {
|
|||||||
fun test(a : Any?) {
|
fun test(a : Any?) {
|
||||||
if (a is B) {
|
if (a is B) {
|
||||||
if (a is C) {
|
if (a is C) {
|
||||||
a.<!AMBIGUITY!>bar<!>();
|
a.bar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -8,6 +8,6 @@ interface B {
|
|||||||
|
|
||||||
fun test(c: Any) {
|
fun test(c: Any) {
|
||||||
if (c is B && c is A) {
|
if (c is B && c is A) {
|
||||||
c.<!AMBIGUITY!>foo<!><String, Int>()
|
c.foo<String, Int>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -10,6 +10,6 @@ interface B {
|
|||||||
|
|
||||||
fun test(c: Any) {
|
fun test(c: Any) {
|
||||||
if (c is B && c is A) {
|
if (c is B && c is A) {
|
||||||
c.<!AMBIGUITY!>foo<!>()
|
c.foo()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-14
@@ -17,37 +17,37 @@ interface C {
|
|||||||
|
|
||||||
fun foo(x: Any?) {
|
fun foo(x: Any?) {
|
||||||
if (x is A && x is B) {
|
if (x is A && x is B) {
|
||||||
x.<!AMBIGUITY!>foo<!>().<!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String>() }
|
x.foo().checkType { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||||
x.<!AMBIGUITY!>foo<!>().<!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String?>() }
|
x.foo().checkType { _<String?>() }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x is B && x is A) {
|
if (x is B && x is A) {
|
||||||
x.<!AMBIGUITY!>foo<!>().<!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String>() }
|
x.foo().checkType { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||||
x.<!AMBIGUITY!>foo<!>().<!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String?>() }
|
x.foo().checkType { _<String?>() }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x is A && x is C) {
|
if (x is A && x is C) {
|
||||||
x.<!AMBIGUITY!>foo<!>().<!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String>() }
|
x.foo().checkType { _<String>() }
|
||||||
x.<!AMBIGUITY!>foo<!>().<!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String?>() }
|
x.foo().checkType { <!INAPPLICABLE_CANDIDATE!>_<!><String?>() }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x is C && x is A) {
|
if (x is C && x is A) {
|
||||||
x.<!AMBIGUITY!>foo<!>().<!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String>() }
|
x.foo().checkType { _<String>() }
|
||||||
x.<!AMBIGUITY!>foo<!>().<!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String?>() }
|
x.foo().checkType { <!INAPPLICABLE_CANDIDATE!>_<!><String?>() }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x is A && x is B && x is C) {
|
if (x is A && x is B && x is C) {
|
||||||
x.<!AMBIGUITY!>foo<!>().<!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String>() }
|
x.foo().checkType { _<String>() }
|
||||||
x.<!AMBIGUITY!>foo<!>().<!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String?>() }
|
x.foo().checkType { <!INAPPLICABLE_CANDIDATE!>_<!><String?>() }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x is B && x is A && x is C) {
|
if (x is B && x is A && x is C) {
|
||||||
x.<!AMBIGUITY!>foo<!>().<!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String>() }
|
x.foo().checkType { _<String>() }
|
||||||
x.<!AMBIGUITY!>foo<!>().<!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String?>() }
|
x.foo().checkType { <!INAPPLICABLE_CANDIDATE!>_<!><String?>() }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x is B && x is C && x is A) {
|
if (x is B && x is C && x is A) {
|
||||||
x.<!AMBIGUITY!>foo<!>().<!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String>() }
|
x.foo().checkType { _<String>() }
|
||||||
x.<!AMBIGUITY!>foo<!>().<!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String?>() }
|
x.foo().checkType { <!INAPPLICABLE_CANDIDATE!>_<!><String?>() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -14,6 +14,6 @@ interface B : Common {
|
|||||||
|
|
||||||
fun test(c: Common) {
|
fun test(c: Common) {
|
||||||
if (c is B && c is A) {
|
if (c is B && c is A) {
|
||||||
c.<!AMBIGUITY!>foo<!>().<!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String>() }
|
c.foo().checkType { _<String>() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -10,6 +10,6 @@ interface B {
|
|||||||
|
|
||||||
fun test(c: Any) {
|
fun test(c: Any) {
|
||||||
if (c is B && c is A) {
|
if (c is B && c is A) {
|
||||||
c.<!AMBIGUITY!>foo<!>().<!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String>() }
|
c.foo().checkType { _<String>() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -13,9 +13,9 @@ interface B: A {
|
|||||||
|
|
||||||
fun test(a: A) {
|
fun test(a: A) {
|
||||||
if (a is B && a is C) {
|
if (a is B && a is C) {
|
||||||
a.<!AMBIGUITY!>foo<!> = ""
|
a.foo = ""
|
||||||
a.<!AMBIGUITY!>foo<!> = null
|
a.foo = null
|
||||||
|
|
||||||
a.<!AMBIGUITY!>foo<!>.<!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String>() }
|
a.foo.checkType { _<String>() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -13,8 +13,8 @@ interface B: A {
|
|||||||
|
|
||||||
fun test(a: A) {
|
fun test(a: A) {
|
||||||
if (a is B && a is C) {
|
if (a is B && a is C) {
|
||||||
a.<!AMBIGUITY!>foo<!> = ""
|
a.foo = ""
|
||||||
a.<!AMBIGUITY!>foo<!> = null
|
a.foo = null
|
||||||
a.<!AMBIGUITY!>foo<!>
|
a.foo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -28,11 +28,11 @@ fun test() {
|
|||||||
x.foo().checkType { _<CharSequence?>() }
|
x.foo().checkType { _<CharSequence?>() }
|
||||||
|
|
||||||
if (x is B && x is C) {
|
if (x is B && x is C) {
|
||||||
x.<!AMBIGUITY!>foo<!>().<!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><CharSequence?>() }
|
x.foo().checkType { <!INAPPLICABLE_CANDIDATE!>_<!><CharSequence?>() }
|
||||||
x.baz("")
|
x.baz("")
|
||||||
x.<!AMBIGUITY!>baz<!>(1).<!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><Unit>() }
|
x.baz(1).checkType { <!INAPPLICABLE_CANDIDATE!>_<!><Unit>() }
|
||||||
x.<!AMBIGUITY!>baz<!>(1, 2)
|
x.baz(1, 2)
|
||||||
|
|
||||||
x.<!AMBIGUITY!>foobar<!>().<!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><String>() }
|
x.foobar().checkType { _<String>() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -10,6 +10,6 @@ interface B {
|
|||||||
|
|
||||||
fun test(c: Any) {
|
fun test(c: Any) {
|
||||||
if (c is B && c is A) {
|
if (c is B && c is A) {
|
||||||
c.<!AMBIGUITY!>foo<!><String, Int>().<!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><Int>() }
|
c.foo<String, Int>().checkType { _<Int>() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user