Scala 2.13 編譯器會在 -Xsource:3
旗標中發出有用的遷移警告。
在移至 Scala 3 編譯器之前,建議在 Scala 2 中啟用此旗標並處理新的警告。
還有一個變體 -Xsource:3-cross
;請參閱下方。注意:在 Scala 2.13.13 中啟用 -Xsource:3-cross
會中斷二進位相容性,請參閱 scala/bug#12961 以取得詳細資訊。
此頁面說明旗標背後的詳細資訊。使用 scalac -Xsource:help
顯示概觀。
遷移與跨建置
在 Scala 2.13.13 及更新版本中,-Xsource:3
旗標有兩個變體
Xsource:3
啟用與將程式碼庫遷移至 Scala 3 相關的警告。除了新的警告之外,此旗標還會啟用某些良性的 Scala 3 語法,例如import p.*
。Xsource:3-cross
適用於在 Scala 2 和 3 之間進行較長時間跨建置的專案。對於某些會觸發-Xsource:3
警告的語言結構,其行為會變更以符合 Scala 3。
此頁面下方列出個別警告的詳細資訊。
致命警告和快速修正
預設情況下,Scala 2.13 發出的 Scala 3 遷移警告是致命的,亦即會報告為錯誤。這可以使用 -Wconf
變更,例如 -Wconf:cat=scala3-migration:w
會將其變更為報告為警告。或者,-Xmigration
也有相同的效果。
@nowarn
註解 可用於抑制個別警告,這也適用於已啟用致命警告的情況。
Scala 2.13 編譯器為許多 Scala 3 遷移警告實作快速修正。快速修正會顯示在基於 Metals 的 IDE 中(尚未出現在 IntelliJ 中),而且可以使用 -quickfix
旗標將其直接套用至原始碼,例如 -quickfix:cat=scala3-migration
。另請參閱 scalac -quickfix:help
。
啟用的 Scala 3 語法
-Xsource:3
旗標會在 Scala 2 中啟用下列 Scala 3 語法
匯入 p.*
匯入 p.m 為 n
匯入 p.{given, *}
case C(xs*)
作為case C(xs @ _*)
的別名A & B
類型交集作為A with B
的別名- 選擇方法
x.f
會執行 eta 展開 (x.f _
),即使沒有預期的類型
Scala 3 遷移警告詳情
許多 Scala 3 遷移警告都很容易理解,且在 -Xsource:3
和 -Xsource:3-cross
下相同,例如,對於沒有明確類型的隱式定義
scala> object O { implicit val s = "" }
^
error: Implicit definition must have explicit type (inferred String) [quickfixable]
以下幾段說明 -Xsource:3
和 -Xsource:3-cross
之間行為的變化。
影響二進制編碼的變更
從 Scala 2.13.13 開始,在 -Xsource:3-cross
下有 3 項變更會影響類別檔案的二進制編碼。對於所有這些變更,-Xsource:3
下會發出致命警告。
- 案例類別的建構函數修飾詞 (
case class C private[p] (x: Int)
) 會複製到合成apply
和copy
方法。 - 案例類別的合成伴隨物件不再延伸
FunctionN
。 - 覆寫沒有明確回傳類型的函數會從父項繼承回傳類型(而不是使用函數主體的推斷類型)。
對於已經使用 Scala 2 和 Scala 3 進行跨版本建置,且兩個版本都有現有發布版本的專案,啟用 -Xsource:3-cross
會中斷二進制相容性。例如,如果函式庫定義
trait A { def f: Object }
class B extends A { def f = "hi" }
- 啟用
-Xsource:3-cross
會中斷 Scala 2.13 的二進制相容性:現有發布版本有A.f: String
,新版本會有A.f: Object
- 新增明確的結果類型
A.f: String
會破壞 Scala 3 的二進位相容性:現有版本有A.f: Object
可以使用依版本而定的原始檔解決此問題,請參閱 scala/scala-xml#675 作為範例。
目前難以解決案例伴侶 FunctionN
父類變更的問題 (Scala 2.13.13),解決方案正在 scala/bug#12961 討論中。
語言語意的變更
下表顯示 -Xsource:3-cross
採用 Scala 3 語言功能語意的案例。
功能 | -Xsource:3 |
-Xsource:3-cross |
---|---|---|
(x: Any) + "" 已棄用 |
棄用警告 | 無法編譯,無法推斷隱含的 any2stringadd |
三引號字串和原始插補中的 Unicode 逸出字元 ("""\u0061""" ) |
致命警告,已處理逸出字元 | 未處理逸出字元 |
前導中綴運算子會繼續前一行 1 | 致命警告,第二行是獨立的表達式 | 運算會繼續前一行 |
使用 StringContext 對字串插補器進行去糖 |
如果插補參照與 scala.StringContext 不同的範圍內的 StringContext ,則會產生致命警告 |
去糖始終使用 scala.StringContext |
在封裝前綴 p 中找到類型 p.A 的隱含值 |
致命警告 | 封裝前綴 p 不再是隱含搜尋範圍的一部分 |
範例 1
def f =
1
+ 2