Scala 2.13で-Xsource:3を指定すると変更される挙動一覧

Scalaコンパイラには、ある程度最近のversionから -Xsource:バージョン という、少し将来のversionの挙動に近づけるオプションがあります。

Scala 2.13.3時点で -Xsource:3 を指定できるわけですが、その場合の挙動の変更一覧を、scala/scalaをgit grepしてコンパイラのコードを読んで調べたので書いておきます。

ちなみに、当初2.14が出る予定だったので、Scala 2.13の最初の方は -Xsource:2.14 という指定方法だったのですが、2.14無くなったので、dottyに向けて -Xsource:3 となりました。

Symbolリテラルが警告ではなくエラー

https://github.com/scala/scala/blob/v2.13.3/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala#L1336

for変数定義にvalがあると警告ではなくエラー

https://github.com/scala/scala/blob/v2.13.3/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala#L1930

scala> for { a <- Option(1); val b = 2 } yield a
                                   ^
       error: `val` keyword in for comprehension is unsupported: instead, bind the value without `val`

view boundが警告ではなくエラー

procedure syntaxが警告ではなくエラー

trait parameter使え、と出る場合があるらしいけれど、これは少なくとも2.13.3時点では、間違ったメッセージでは???

https://github.com/scala/scala/blob/v2.13.3/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala#L3038

Early Definitionsが警告ではなくエラー

https://github.com/scala/scala/blob/v2.13.3/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala#L3060

package objectが他のclassやtraitを継承していると警告出るようになる

https://github.com/scala/scala/blob/v2.13.3/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala#L3104-L3106

途中に改行あった場合の挙動の変更(以下の結果が変わる)

オプションなしだと警告、オプションありだと警告出ずに勝手に?変わる

def foo: Int = {
  1
  + 2
}
  • オプションなしだと 2
  • オプションありだと 3

トリプルクオート内のunicode escapeの挙動が変わる

https://github.com/scala/scala/blob/v2.13.3/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala#L880

"""\u0041"""

  • オプションなしだと警告出つつ A に変わる
  • オプションありだと "\u0041" のまま(警告なし)

上記と同じく raw のstring interpolation中のunicode escapeの挙動が変わる

https://github.com/scala/scala/blob/v2.13.3/src/compiler/scala/tools/reflect/FastStringInterpolator.scala#L35

"Adapting argument list" が警告ではなくエラー

https://github.com/scala/scala/blob/v2.13.3/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala#L95

(2.13で非推奨な) implicit def any2stringadd が強制的に無効化

https://github.com/scala/scala/blob/v2.13.3/src/compiler/scala/tools/nsc/typechecker/Contexts.scala#L1056

scala> None + " a"
            ^
       error: value + is not a member of object None

existential typeに関する挙動の変更?

(よくわかってない。後で追記するかも)

https://github.com/scala/scala/blob/v2.13.3/src/compiler/scala/tools/nsc/typechecker/Infer.scala#L907

親が () 付与して定義されてるメソッドなのに、子供でoverrideするときに () ついてなかったら警告ではなくエラー

scala> trait A { def foo(): Unit }
trait A

scala> class B extends A { def foo: Unit = {} }
                               ^
       error: method without a parameter list overrides a method with a single empty one

https://github.com/scala/scala/blob/v2.13.3/src/compiler/scala/tools/nsc/typechecker/Namers.scala#L1474

上記の逆でも警告ではなくエラー

https://github.com/scala/scala/blob/v2.13.3/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala#L441

Note that assignments in argument position are no longer allowed since Scala 2.13 のエラー関連

っぽいが、2.13から出る気がするし、よくわからないので後で調べたい

https://github.com/scala/scala/blob/v2.13.3/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala#L532

親にあるnested classと同じ名前のclassを子に定義すると、警告ではなくエラー

scala> trait A { class C }
trait A

scala> trait B extends A { class C }
                                 ^
       error: shadowing a nested class of a parent is unsupported but class C shadows class C defined in trait A; rename the class to something else

Eta Expansion関連のなにか

TODO 後で追記?

case classのコンストラクタのスコープ(private, protectedなど)を、コンパニオンのapplyやcopyが引き継ぐかどうか?

オプションなしだと引き継がない(あくまでapplyなどはpublic)