Closed
Description
Compiler version
3.1.2 and 3.1.3-RC1-bin-20220407-31f871c-NIGHTLY
Minimized code
This arose while working on #14294, the examples below are extracted from our test suite and modified with an @unchecked
annotation.
Example 1
object Ex { def unapply(p: Any): Option[_ <: Int] = null }
object Foo { val Ex(_) = null: @unchecked }
(extracted from tests/pos/extractor-types.scala )
Example 2
import scala.scalajs.js
object Test {
val obj = new js.Object {
val a = 42
val b = "foo"
}
val entries = js.Object.entries(obj)
val js.Tuple2(k, v) = entries(0): @unchecked
}
(extracted from this Scala.js test)
Output
Example 1
$ scalac extractor-types.scala
-- Error: extractor-types.scala:2:17 -------------------------------------------
2 |object Foo { val Ex(_) = null: @unchecked }
| ^^^^^
| class Null cannot be used in runtime type tests
Example 2
$ scalac -scalajs -cp $(cs fetch -p org.scala-js:scalajs-library_2.13:1.9.0) ObjectTest.scala
-- Error: ObjectTest.scala:10:6 ------------------------------------------------
10 | val js.Tuple2(k, v) = entries(0): @unchecked
| ^^^^^^^^^^^^^^^
|isInstanceOf[scala.scalajs.js.Tuple2] not supported because it is a JS trait
Expectation
Both examples compile without the @unchecked
annotation.
Both examples compile with Scala 2.13.
Since @unchecked
was added to suppress the refutable pattern binding warning (currently under -source future), I expected compilation to be successful here as well.
It seems that adding @unchecked
is causing a type test to be generated that wouldn't be otherwise. Below is a diff of -Xprint:typer on the first example:
[[syntax trees at end of typer]] // extractor-types.scala
package <empty> {
final lazy module val Ex: Ex = new Ex()
final module class Ex() extends Object() { this: Ex.type =>
def unapply(p: Any): Option[? >: Nothing <: Int] = null
}
final lazy module val Foo: Foo = new Foo()
final module class Foo() extends Object() { this: Foo.type =>
- null:Null @unchecked match
+ null:Null @unchecked:Null @unchecked @unchecked match
{
- case Ex(_) => ()
+ case Ex(_):Null => ()
}
}
}