Closed
Description
Compiler version
3.0.0 and 3.0.1-RC2
Minimized code
intf.java
interface Intf {
void test(Object... x);
}
impl.scala
class Impl extends Intf:
override def test(x: Object | Null*): Unit = ???
Output
scalac3 -Yexplicit-nulls -explain impl.scala
1 |class Impl extends Intf:
| ^
| error overriding method test in trait Intf of type (x$0: Array[? <: Object | Null]): Unit;
| method test of type (x: Array[? <: (Object | Null) & AnyRef]): Unit has incompatible type
`-explain` stuff
Explanation
===========
I tried to show that
(x: Array[? <: (Object | Null) & AnyRef]): Unit
conforms to
(x$0: Array[? <: Object | Null]): Unit
but the comparison trace ended with `false`:
==> (x: Array[? <: (Object | Null) & AnyRef]): Unit <: (x$0: Array[? <: Object | Null]): Unit
==> (x: Array[? <: (Object | Null) & AnyRef]): Unit <: (x$0: Array[? <: Object | Null]): Unit (recurring)
==> Array[? <: (Object | Null) & AnyRef] <: Array[? <: Object | Null] in frozen constraint
==> Array[? <: (Object | Null) & AnyRef] <: Array[? <: Object | Null] (recurring) in frozen constraint
==> Nothing <: Nothing in frozen constraint
==> Nothing <: Nothing (recurring) in frozen constraint
<== Nothing <: Nothing (recurring) in frozen constraint = true
<== Nothing <: Nothing in frozen constraint = true
==> Any <: (Object | Null) & AnyRef in frozen constraint
==> Any <: (Object | Null) & AnyRef (recurring) in frozen constraint
==> Any <: Object | Null (recurring) in frozen constraint
==> Any <: Object (recurring) in frozen constraint
<== Any <: Object (recurring) in frozen constraint = false
==> Any <: Null (recurring) in frozen constraint
<== Any <: Null (recurring) in frozen constraint = false
<== Any <: Object | Null (recurring) in frozen constraint = false
<== Any <: (Object | Null) & AnyRef (recurring) in frozen constraint = false
<== Any <: (Object | Null) & AnyRef in frozen constraint = false
==> Nothing <: Nothing in frozen constraint
==> Nothing <: Nothing (recurring) in frozen constraint
<== Nothing <: Nothing (recurring) in frozen constraint = true
<== Nothing <: Nothing in frozen constraint = true
==> (Object | Null) & AnyRef <: Any in frozen constraint
==> (Object | Null) & AnyRef <: Any (recurring) in frozen constraint
<== (Object | Null) & AnyRef <: Any (recurring) in frozen constraint = true
<== (Object | Null) & AnyRef <: Any in frozen constraint = true
==> (Object | Null) & AnyRef <: Object | Null in frozen constraint
==> (Object | Null) & AnyRef <: Object | Null (recurring) in frozen constraint
==> (Object | Null) & AnyRef <: Object (recurring) in frozen constraint
==> (Object | Null) & AnyRef <: Any (recurring) in frozen constraint
<== (Object | Null) & AnyRef <: Any (recurring) in frozen constraint = true
<== (Object | Null) & AnyRef <: Object (recurring) in frozen constraint = true
<== (Object | Null) & AnyRef <: Object | Null (recurring) in frozen constraint = true
<== (Object | Null) & AnyRef <: Object | Null in frozen constraint = true
<== Array[? <: (Object | Null) & AnyRef] <: Array[? <: Object | Null] (recurring) in frozen constraint = true
<== Array[? <: (Object | Null) & AnyRef] <: Array[? <: Object | Null] in frozen constraint = true
==> Array[? <: Object | Null] <: Array[? <: (Object | Null) & AnyRef] in frozen constraint
==> Array[? <: Object | Null] <: Array[? <: (Object | Null) & AnyRef] (recurring) in frozen constraint
==> Nothing <: Nothing in frozen constraint
==> Nothing <: Nothing (recurring) in frozen constraint
<== Nothing <: Nothing (recurring) in frozen constraint = true
<== Nothing <: Nothing in frozen constraint = true
==> Any <: Object | Null in frozen constraint
==> Any <: Object | Null (recurring) in frozen constraint
==> Any <: Object (recurring) in frozen constraint
==> Any <: Any (recurring) in frozen constraint
<== Any <: Any (recurring) in frozen constraint = true
<== Any <: Object (recurring) in frozen constraint = true
<== Any <: Object | Null (recurring) in frozen constraint = true
<== Any <: Object | Null in frozen constraint = true
==> Any <: (Object | Null) & AnyRef in frozen constraint
==> Any <: (Object | Null) & AnyRef (recurring) in frozen constraint
==> Any <: Object | Null (recurring) in frozen constraint
==> Any <: Object (recurring) in frozen constraint
<== Any <: Object (recurring) in frozen constraint = false
==> Any <: Null (recurring) in frozen constraint
<== Any <: Null (recurring) in frozen constraint = false
<== Any <: Object | Null (recurring) in frozen constraint = false
<== Any <: (Object | Null) & AnyRef (recurring) in frozen constraint = false
<== Any <: (Object | Null) & AnyRef in frozen constraint = false
<== Array[? <: Object | Null] <: Array[? <: (Object | Null) & AnyRef] (recurring) in frozen constraint = false
<== Array[? <: Object | Null] <: Array[? <: (Object | Null) & AnyRef] in frozen constraint = false
<== (x: Array[? <: (Object | Null) & AnyRef]): Unit <: (x$0: Array[? <: Object | Null]): Unit (recurring) = false
<== (x: Array[? <: (Object | Null) & AnyRef]): Unit <: (x$0: Array[? <: Object | Null]): Unit = false
The tests were made under the empty constraint
Expectation
The type signature Object | Null*
should be an appropriate match for Object...
and allow the code to compile.
Another piece of example code
intf.java
interface Intf {
void test(int x);
void test(Object... x);
}
impl.scala
class Impl extends Intf:
override def test(x: Int): Unit = ???
override def test(x: Array[_ <: Object | Null]): Unit = ???
note: Array
is used here because scala varargs is not compatible with java's when the method is overloaded. For non-Object
varargs in this situation an Array
is accepted by the compiler, but for Object
varargs we hit the same bug.
Output (scalac3 -Yexplicit-nulls -explain impl.scala
):
-- [E163] Declaration Error: impl.scala:3:15 ------------------------------------------------------------------------------------------------------------------------------------------------------
3 | override def test(x: Array[_ <: Object | Null]): Unit = ???
| ^
| error overriding method test in trait Intf of type (x$0: Array[? <: Object | Null]): Unit;
| method test of type (x: Array[? <: Object | Null]): Unit has incompatible type
Explanation
===========
I tried to show that
(x: Array[? <: Object | Null]): Unit
conforms to
(x$0: Array[? <: Object | Null]): Unit
but the comparison trace ended with `false`:
==> (x: Array[? <: Object | Null]): Unit <: (x$0: Array[? <: Object | Null]): Unit
==> (x: Array[? <: Object | Null]): Unit <: (x$0: Array[? <: Object | Null]): Unit (recurring)
==> Array[? <: Object | Null] <: Array[? <: Object | Null] in frozen constraint
==> Array[? <: Object | Null] <: Array[? <: Object | Null] (recurring) in frozen constraint
==> scala.type <: (scala : scala.type) in frozen constraint
==> scala.type <: (scala : scala.type) (recurring) in frozen constraint
<== scala.type <: (scala : scala.type) (recurring) in frozen constraint = true
<== scala.type <: (scala : scala.type) in frozen constraint = true
==> Nothing <: Nothing in frozen constraint
==> Nothing <: Nothing (recurring) in frozen constraint
<== Nothing <: Nothing (recurring) in frozen constraint = true
<== Nothing <: Nothing in frozen constraint = true
==> Any <: Object | Null in frozen constraint
==> Any <: Object | Null (recurring) in frozen constraint
==> Any <: Object (recurring) in frozen constraint
<== Any <: Object (recurring) in frozen constraint = false
==> Any <: Null (recurring) in frozen constraint
<== Any <: Null (recurring) in frozen constraint = false
<== Any <: Object | Null (recurring) in frozen constraint = false
<== Any <: Object | Null in frozen constraint = false
==> Nothing <: Nothing in frozen constraint
==> Nothing <: Nothing (recurring) in frozen constraint
<== Nothing <: Nothing (recurring) in frozen constraint = true
<== Nothing <: Nothing in frozen constraint = true
==> Object | Null <: Any in frozen constraint
==> Object | Null <: Any (recurring) in frozen constraint
==> Object <: Any (recurring) in frozen constraint
<== Object <: Any (recurring) in frozen constraint = true
==> Null <: Any (recurring) in frozen constraint
<== Null <: Any (recurring) in frozen constraint = true
<== Object | Null <: Any (recurring) in frozen constraint = true
<== Object | Null <: Any in frozen constraint = true
==> Object | Null <: Object | Null in frozen constraint
==> Object | Null <: Object | Null (recurring) in frozen constraint
==> Object <: Object | Null (recurring) in frozen constraint
==> Object <: Object (recurring) in frozen constraint
==> Object <: Any (recurring) in frozen constraint
<== Object <: Any (recurring) in frozen constraint = true
<== Object <: Object (recurring) in frozen constraint = true
<== Object <: Object | Null (recurring) in frozen constraint = true
==> Null <: Object | Null (recurring) in frozen constraint
==> Null <: Object (recurring) in frozen constraint
==> Null <: Any (recurring) in frozen constraint
<== Null <: Any (recurring) in frozen constraint = true
<== Null <: Object (recurring) in frozen constraint = true
<== Null <: Object | Null (recurring) in frozen constraint = true
<== Object | Null <: Object | Null (recurring) in frozen constraint = true
<== Object | Null <: Object | Null in frozen constraint = true
<== Array[? <: Object | Null] <: Array[? <: Object | Null] (recurring) in frozen constraint = true
<== Array[? <: Object | Null] <: Array[? <: Object | Null] in frozen constraint = true
==> Array[? <: Object | Null] <: Array[? <: Object | Null] in frozen constraint
==> Array[? <: Object | Null] <: Array[? <: Object | Null] (recurring) in frozen constraint
==> (scala : scala.type) <: scala.type in frozen constraint
==> (scala : scala.type) <: scala.type (recurring) in frozen constraint
<== (scala : scala.type) <: scala.type (recurring) in frozen constraint = true
<== (scala : scala.type) <: scala.type in frozen constraint = true
==> Nothing <: Nothing in frozen constraint
==> Nothing <: Nothing (recurring) in frozen constraint
<== Nothing <: Nothing (recurring) in frozen constraint = true
<== Nothing <: Nothing in frozen constraint = true
==> Any <: Object | Null in frozen constraint
==> Any <: Object | Null (recurring) in frozen constraint
==> Any <: Object (recurring) in frozen constraint
==> Any <: Any (recurring) in frozen constraint
<== Any <: Any (recurring) in frozen constraint = true
<== Any <: Object (recurring) in frozen constraint = true
<== Any <: Object | Null (recurring) in frozen constraint = true
<== Any <: Object | Null in frozen constraint = true
==> Any <: Object | Null in frozen constraint
==> Any <: Object | Null (recurring) in frozen constraint
==> Any <: Object (recurring) in frozen constraint
<== Any <: Object (recurring) in frozen constraint = false
==> Any <: Null (recurring) in frozen constraint
<== Any <: Null (recurring) in frozen constraint = false
<== Any <: Object | Null (recurring) in frozen constraint = false
<== Any <: Object | Null in frozen constraint = false
<== Array[? <: Object | Null] <: Array[? <: Object | Null] (recurring) in frozen constraint = false
<== Array[? <: Object | Null] <: Array[? <: Object | Null] in frozen constraint = false
<== (x: Array[? <: Object | Null]): Unit <: (x$0: Array[? <: Object | Null]): Unit (recurring) = false
<== (x: Array[? <: Object | Null]): Unit <: (x$0: Array[? <: Object | Null]): Unit = false
The tests were made under the empty constraint
1 error found