FIR checker: check super reference

This change touches the following diagnostics to make them behave closer
to FE1.0

* SUPER_NOT_AVAILABLE
* SUPER_IS_NOT_AN_EXPRESSION
* INSTANCE_ACCESS_BEFORE_SUPER_CALL
* NOT_A_SUPERTYPE

Other than tweaking the diagnostics, this change also alters resolution
by consider marking `super` with mismatched type parameter as
errorenous. As a result, the following code no longer resolves.

```
class A: B() {
  fun test() {
    super<String>.length
    //            ^^^^^^ FIR currently resolves this to `String.length`.
    //                   With this change, `length` becomes unresolved
    //                   instead
  }
}
```

Also, now we report `UNRESOLVED_LABEL` on unresolved label on `super`
reference, though FE1.0 reports `UNRESOLVED_REFERENCE`.

All the errors above are reported as ConeDiagnostics and hence some
checkers are deleted.

In addition, it also suppresses more downstream (mostly unresolved)
errors if the receiver has errors. FE1.0 doesn't do it for all the cases
we have here. But it seems nicer to reduce these "redundant" unresolved
errors.
This commit is contained in:
Tianyu Geng
2021-06-23 16:15:02 -07:00
committed by Ivan Kochurkin
parent bcf6202863
commit 280c445783
45 changed files with 257 additions and 189 deletions
@@ -1,11 +0,0 @@
// http://youtrack.jetbrains.net/issue/KT-413
open class A {
fun f() {}
}
class B : A() {
fun g() {
super?.<!UNRESOLVED_REFERENCE!>f<!>()
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// http://youtrack.jetbrains.net/issue/KT-413
open class A {
@@ -6,12 +6,12 @@ interface Trait {
class Outer : Trait {
class Nested {
val t = this<!UNRESOLVED_LABEL!>@Outer<!>.<!UNRESOLVED_REFERENCE!>bar<!>()
val s = super@Outer.<!UNRESOLVED_REFERENCE!>bar<!>()
val t = this<!UNRESOLVED_LABEL!>@Outer<!>.bar()
val s = super<!UNRESOLVED_LABEL!>@Outer<!>.bar()
inner class NestedInner {
val t = this<!UNRESOLVED_LABEL!>@Outer<!>.<!UNRESOLVED_REFERENCE!>bar<!>()
val s = super@Outer.<!UNRESOLVED_REFERENCE!>bar<!>()
val t = this<!UNRESOLVED_LABEL!>@Outer<!>.bar()
val s = super<!UNRESOLVED_LABEL!>@Outer<!>.bar()
}
}
@@ -7,8 +7,8 @@ class Outer {
class Nested {
fun f() = <!UNRESOLVED_REFERENCE!>function<!>()
fun g() = <!UNRESOLVED_REFERENCE!>property<!>
fun h() = this<!UNRESOLVED_LABEL!>@Outer<!>.<!UNRESOLVED_REFERENCE!>function<!>()
fun i() = this<!UNRESOLVED_LABEL!>@Outer<!>.<!UNRESOLVED_REFERENCE!>property<!>
fun h() = this<!UNRESOLVED_LABEL!>@Outer<!>.function()
fun i() = this<!UNRESOLVED_LABEL!>@Outer<!>.property
}
inner class Inner {
@@ -4,10 +4,10 @@ interface Iterator<out T> {
fun <R> map(transform: (element: T) -> R) : Iterator<R> =
object : Iterator<R> {
override fun next() : R = transform(this<!UNRESOLVED_LABEL!>@map<!>.<!UNRESOLVED_REFERENCE!>next<!>())
override fun next() : R = transform(this<!UNRESOLVED_LABEL!>@map<!>.next())
override val hasNext : Boolean
// There's no 'this' associated with the map() function, only this of the Iterator class
get() = this<!UNRESOLVED_LABEL!>@map<!>.<!UNRESOLVED_REFERENCE!>hasNext<!>
get() = this<!UNRESOLVED_LABEL!>@map<!>.hasNext
}
}
@@ -7,7 +7,7 @@ open class Base<T>(p: Any?) {
class D: Base<Int>(1) {
inner class B : Base<Int> {
constructor() : super(foo1(1))
constructor(x: Int) : super(this<!UNRESOLVED_LABEL!>@B<!>.<!UNRESOLVED_REFERENCE!>foo1<!>(1))
constructor(x: Int) : super(this<!UNRESOLVED_LABEL!>@B<!>.foo1(1))
constructor(x: Int, y: Int) : super(this@D.foo1(1))
}
}
@@ -7,6 +7,6 @@ fun Base.foo() {
class B : Base {
constructor() : super(foo1())
constructor(x: Int) : super(this@foo.foo1())
constructor(x: Int, y: Int) : super(this<!UNRESOLVED_LABEL!>@B<!>.<!UNRESOLVED_REFERENCE!>foo1<!>())
constructor(x: Int, y: Int) : super(this<!UNRESOLVED_LABEL!>@B<!>.foo1())
}
}
@@ -8,6 +8,6 @@ fun Base<Int>.foo() {
constructor() : super(foo1(<!ARGUMENT_TYPE_MISMATCH!>""<!>))
constructor(x: Int) : super(foo1(1))
constructor(x: Int, y: Int) : super(this@foo.foo1(12))
constructor(x: Int, y: Int, z: Int) : super(this<!UNRESOLVED_LABEL!>@B<!>.<!UNRESOLVED_REFERENCE!>foo1<!>(""))
constructor(x: Int, y: Int, z: Int) : super(this<!UNRESOLVED_LABEL!>@B<!>.foo1(""))
}
}
@@ -6,6 +6,6 @@ class Outer {
}
constructor(x: Int)
constructor(x: Int, y: Int, z: Int = <!TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!RESOLUTION_TO_CLASSIFIER!>Inner<!>().<!UNRESOLVED_REFERENCE!>prop<!> + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.<!UNRESOLVED_REFERENCE!>Inner<!>().prop<!>) :
this(<!ARGUMENT_TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!RESOLUTION_TO_CLASSIFIER!>Inner<!>().<!UNRESOLVED_REFERENCE!>prop<!> + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.<!UNRESOLVED_REFERENCE!>Inner<!>().prop<!>)
constructor(x: Int, y: Int, z: Int = <!TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!RESOLUTION_TO_CLASSIFIER!>Inner<!>().<!UNRESOLVED_REFERENCE!>prop<!> + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.Inner().prop<!>) :
this(<!ARGUMENT_TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!RESOLUTION_TO_CLASSIFIER!>Inner<!>().<!UNRESOLVED_REFERENCE!>prop<!> + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.Inner().prop<!>)
}
@@ -8,8 +8,8 @@ class A {
constructor() : this(
{
<!ARGUMENT_TYPE_MISMATCH, TYPE_MISMATCH!><!UNRESOLVED_REFERENCE!>foo<!>() +
<!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.<!UNRESOLVED_REFERENCE!>foo<!>() +
this<!UNRESOLVED_LABEL!>@A<!>.<!UNRESOLVED_REFERENCE!>foo<!>() +
<!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.foo() +
this<!UNRESOLVED_LABEL!>@A<!>.foo() +
<!UNRESOLVED_REFERENCE!>foobar<!>()<!>
})
}
@@ -2,6 +2,6 @@
class A {
fun foo() = 1
constructor(x: Int)
constructor(x: Int, y: Int, z: Int = <!TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>foo<!>() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.<!UNRESOLVED_REFERENCE!>foo<!>()<!>) :
this(<!ARGUMENT_TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>foo<!>() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.<!UNRESOLVED_REFERENCE!>foo<!>()<!>)
constructor(x: Int, y: Int, z: Int = <!TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>foo<!>() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.foo()<!>) :
this(<!ARGUMENT_TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>foo<!>() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.foo()<!>)
}
@@ -6,7 +6,7 @@ class A {
fun foo() = 1
constructor(x: Any?)
constructor() : this(object {
fun bar() = <!UNRESOLVED_REFERENCE!>foo<!>() + this<!UNRESOLVED_LABEL!>@A<!>.<!UNRESOLVED_REFERENCE!>foo<!>() +
<!INAPPLICABLE_CANDIDATE!>foobar<!>() + super@A.<!UNRESOLVED_REFERENCE!>hashCode<!>()
fun bar() = <!UNRESOLVED_REFERENCE!>foo<!>() + this<!UNRESOLVED_LABEL!>@A<!>.foo() +
<!INAPPLICABLE_CANDIDATE!>foobar<!>() + super<!UNRESOLVED_LABEL!>@A<!>.hashCode()
})
}
@@ -5,7 +5,7 @@ fun A.foobar() = 3
class A {
fun foo() = 1
constructor( x: Any = object {
fun bar() = <!UNRESOLVED_REFERENCE!>foo<!>() + this<!UNRESOLVED_LABEL!>@A<!>.<!UNRESOLVED_REFERENCE!>foo<!>() +
fun bar() = <!UNRESOLVED_REFERENCE!>foo<!>() + this<!UNRESOLVED_LABEL!>@A<!>.foo() +
<!INAPPLICABLE_CANDIDATE!>foobar<!>()
})
}
@@ -2,6 +2,6 @@
class A {
val prop = 1
constructor(x: Int)
constructor(x: Int, y: Int, z: Int = <!TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>prop<!> + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.<!UNRESOLVED_REFERENCE!>prop<!><!>) :
this(<!ARGUMENT_TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>prop<!> + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.<!UNRESOLVED_REFERENCE!>prop<!><!>)
constructor(x: Int, y: Int, z: Int = <!TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>prop<!> + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.prop<!>) :
this(<!ARGUMENT_TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>prop<!> + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.prop<!>)
}
@@ -2,6 +2,6 @@
open class B(x: Int)
class A : B {
val prop = 1
constructor(x: Int, y: Int = <!TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>prop<!> + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.<!UNRESOLVED_REFERENCE!>prop<!><!>) :
super(<!ARGUMENT_TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>prop<!> + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.<!UNRESOLVED_REFERENCE!>prop<!><!>)
constructor(x: Int, y: Int = <!TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>prop<!> + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.prop<!>) :
super(<!ARGUMENT_TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>prop<!> + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.prop<!>)
}
@@ -3,6 +3,6 @@ open class B(x: Int) {
fun foo() = 1
}
class A : B {
constructor(x: Int, y: Int = <!TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>foo<!>() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.<!UNRESOLVED_REFERENCE!>foo<!>() + super.<!UNRESOLVED_REFERENCE!>foo<!>()<!>) :
super(<!ARGUMENT_TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>foo<!>() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.<!UNRESOLVED_REFERENCE!>foo<!>() + super.<!UNRESOLVED_REFERENCE!>foo<!>()<!>)
constructor(x: Int, y: Int = <!TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>foo<!>() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.foo() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>super<!>.foo()<!>) :
super(<!ARGUMENT_TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>foo<!>() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.foo() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>super<!>.foo()<!>)
}
@@ -4,6 +4,6 @@ open class B(x: Int) {
}
class A : B {
override fun foo() = 2
constructor(x: Int, y: Int = <!TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>foo<!>() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.<!UNRESOLVED_REFERENCE!>foo<!>() + super.<!UNRESOLVED_REFERENCE!>foo<!>()<!>) :
super(<!ARGUMENT_TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>foo<!>() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.<!UNRESOLVED_REFERENCE!>foo<!>() + super.<!UNRESOLVED_REFERENCE!>foo<!>()<!>)
constructor(x: Int, y: Int = <!TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>foo<!>() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.foo() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>super<!>.foo()<!>) :
super(<!ARGUMENT_TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>foo<!>() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.foo() + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>super<!>.foo()<!>)
}
@@ -1,6 +1,6 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
open class B(val prop: Int)
class A : B {
constructor(x: Int, y: Int = <!TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>prop<!> + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.<!UNRESOLVED_REFERENCE!>prop<!> + super.<!UNRESOLVED_REFERENCE!>prop<!><!>) :
super(<!ARGUMENT_TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>prop<!> + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.<!UNRESOLVED_REFERENCE!>prop<!> + super.<!UNRESOLVED_REFERENCE!>prop<!><!>)
constructor(x: Int, y: Int = <!TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>prop<!> + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.prop + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>super<!>.prop<!>) :
super(<!ARGUMENT_TYPE_MISMATCH!>x <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>prop<!> + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.prop + <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>super<!>.prop<!>)
}
+16 -16
View File
@@ -10,34 +10,34 @@ open class C() {
class A<E>() : C(), T {
fun test() {
super
super<T>
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!>
<!SUPER_IS_NOT_AN_EXPRESSION!>super<T><!>
super.foo()
super<T>.foo()
super<C>.bar()
super<T>@A.foo()
super<C>@A.bar()
super<<!OTHER_ERROR, OTHER_ERROR!>E<!>>.<!UNRESOLVED_REFERENCE!>bar<!>()
super<<!OTHER_ERROR, OTHER_ERROR!>E<!>>@A.<!UNRESOLVED_REFERENCE!>bar<!>()
<!NOT_A_SUPERTYPE!>super<Int><!>.<!UNRESOLVED_REFERENCE!>foo<!>()
super<<!NOT_A_SUPERTYPE!>E<!>>.bar()
super<<!NOT_A_SUPERTYPE!>E<!>>@A.bar()
super<<!NOT_A_SUPERTYPE!>Int<!>>.foo()
super<<!SYNTAX!><!>>.<!UNRESOLVED_REFERENCE!>foo<!>()
<!NOT_A_SUPERTYPE!>super<() -> Unit><!>.<!UNRESOLVED_REFERENCE!>foo<!>()
<!NOT_A_SUPERTYPE!>super<Unit><!>.<!UNRESOLVED_REFERENCE!>foo<!>()
super<T>@B.foo()
super<C>@B.bar()
super<<!NOT_A_SUPERTYPE!>() -> Unit<!>>.foo()
super<<!NOT_A_SUPERTYPE!>Unit<!>>.foo()
super<T><!UNRESOLVED_LABEL!>@B<!>.foo()
super<C><!UNRESOLVED_LABEL!>@B<!>.bar()
}
inner class B : T {
fun test() {
super<T>.foo();
<!NOT_A_SUPERTYPE!>super<C><!>.bar()
super<<!NOT_A_SUPERTYPE!>C<!>>.bar()
super<C>@A.bar()
super<T>@A.foo()
super<T>@B.foo()
<!NOT_A_SUPERTYPE!>super<C>@B<!>.<!UNRESOLVED_REFERENCE!>foo<!>()
super<<!NOT_A_SUPERTYPE!>C<!>>@B.foo()
super.foo()
super
super<T>
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!>
<!SUPER_IS_NOT_AN_EXPRESSION!>super<T><!>
}
}
}
@@ -49,9 +49,9 @@ interface G<T> {
class CG : G<Int> {
fun test() {
super<G>.foo() // OK
super<G<Int>>.foo() // Warning
super<G<E>>.foo() // Error
super<G<String>>.foo() // Error
super<G<!TYPE_ARGUMENTS_REDUNDANT_IN_SUPER_QUALIFIER!><Int><!>>.foo() // Warning
super<<!NOT_A_SUPERTYPE!>G<E><!>>.foo() // Error
super<<!NOT_A_SUPERTYPE!>G<String><!>>.foo() // Error
}
}
@@ -1,4 +1,4 @@
fun String.f() {
<!SUPER_NOT_AVAILABLE!>super@f<!>.<!UNRESOLVED_REFERENCE!>compareTo<!>("")
<!SUPER_NOT_AVAILABLE!>super<!>.<!UNRESOLVED_REFERENCE!>compareTo<!>("")
}
<!SUPER_NOT_AVAILABLE!>super@f<!>.compareTo("")
<!SUPER_NOT_AVAILABLE!>super<!>.compareTo("")
}
@@ -1,5 +1,5 @@
fun foo() {
<!SUPER_NOT_AVAILABLE!>super<!>
<!SUPER_NOT_AVAILABLE!>super<!>.<!UNRESOLVED_REFERENCE!>foo<!>()
<!SUPER_NOT_AVAILABLE!>super<Nothing><!>.<!UNRESOLVED_REFERENCE!>foo<!>()
}
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!>
<!SUPER_NOT_AVAILABLE!>super<!>.foo()
<!SUPER_NOT_AVAILABLE!>super<Nothing><!>.foo()
}
@@ -1,12 +0,0 @@
fun any(a : Any) {}
fun notAnExpression() {
any(<!SUPER_NOT_AVAILABLE!>super<!>) // not an expression
if (<!SUPER_NOT_AVAILABLE!>super<!>) {} else {} // not an expression
val x = <!SUPER_NOT_AVAILABLE!>super<!> // not an expression
when (1) {
<!SUPER_NOT_AVAILABLE!>super<!> -> 1 // not an expression
else -> {}
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
fun any(a : Any) {}
fun notAnExpression() {
@@ -22,8 +22,8 @@ class TestSuperForBase : B() {
override fun foo() {
super<Base>.foo()
super<B>.foo()
super<<!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>MyBase<!>>.<!UNRESOLVED_REFERENCE!>foo<!>()
<!NOT_A_SUPERTYPE!>super<U><!>.foo()
super<<!NOT_A_SUPERTYPE!>MyBase<!>>.foo()
super<<!NOT_A_SUPERTYPE!>U<!>>.foo()
}
}
@@ -34,8 +34,8 @@ class TestSuperForGenericBase<T> : GB<T>() {
override fun foo() {
super<GenericBase>.foo()
super<GB>.foo()
super<<!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>MyBase<!>>.<!UNRESOLVED_REFERENCE!>foo<!>()
super<<!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>MyBaseInt<!>>.<!UNRESOLVED_REFERENCE!>foo<!>() // Type arguments don't matter here
<!NOT_A_SUPERTYPE!>super<U><!>.foo()
super<<!NOT_A_SUPERTYPE!>MyBase<!>>.foo()
super<<!NOT_A_SUPERTYPE!>MyBaseInt<!>>.foo() // Type arguments don't matter here
super<<!NOT_A_SUPERTYPE!>U<!>>.foo()
}
}
}