From ac1928aa7ee2e859ccbf0026305fdea85e0706f1 Mon Sep 17 00:00:00 2001 From: Tom Grigg Date: Sun, 6 Mar 2022 22:08:46 -0800 Subject: [PATCH 01/12] Remove dead code --- compiler/src/dotty/tools/dotc/ast/Desugar.scala | 4 ---- 1 file changed, 4 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index 445426ab4118..ca5ae257ec41 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -1656,10 +1656,6 @@ object desugar { Select(rhs, name) } - def checkMode(gen: GenFrom) = - if (gen.checkMode == GenCheckMode.Check) MatchCheck.IrrefutableGenFrom - else MatchCheck.None // refutable paterns were already eliminated in filter step - enums match { case (gen: GenFrom) :: Nil => Apply(rhsSelect(gen, mapName), makeLambda(gen, body)) From a54d521ce5a698512f4e129272a5761eeafaa4ac Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Fri, 4 Mar 2022 17:10:36 +0100 Subject: [PATCH 02/12] introduce infrastructure for 3.2 language features Co-authored-by: Tom Grigg --- .../src/dotty/tools/dotc/config/Feature.scala | 3 +-- .../tools/dotc/config/ScalaSettings.scala | 6 +++++- .../tools/dotc/config/SourceVersion.scala | 5 ++++- compiler/src/dotty/tools/dotc/report.scala | 3 +-- .../dotty/tools/dotc/CompilationTests.scala | 2 +- .../runtime/stdLibPatches/language.scala | 20 ++++++++++++++++--- tests/pos/source-import-3-2-migration.scala | 1 + tests/pos/source-import-3-2.scala | 1 + 8 files changed, 31 insertions(+), 10 deletions(-) create mode 100644 tests/pos/source-import-3-2-migration.scala create mode 100644 tests/pos/source-import-3-2.scala diff --git a/compiler/src/dotty/tools/dotc/config/Feature.scala b/compiler/src/dotty/tools/dotc/config/Feature.scala index 04c7b5872204..868de1f71d76 100644 --- a/compiler/src/dotty/tools/dotc/config/Feature.scala +++ b/compiler/src/dotty/tools/dotc/config/Feature.scala @@ -88,8 +88,7 @@ object Feature: /** If current source migrates to `version`, issue given warning message * and return `true`, otherwise return `false`. */ - def warnOnMigration(msg: Message, pos: SrcPos, - version: SourceVersion)(using Context): Boolean = + def warnOnMigration(msg: Message, pos: SrcPos, version: SourceVersion)(using Context): Boolean = if sourceVersion.isMigrating && sourceVersion.stable == version || (version == `3.0` || version == `3.1` || version == `3.2`) && migrateTo3 then diff --git a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala index 20cbcd136fee..84e5a2881f17 100644 --- a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala +++ b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala @@ -5,6 +5,7 @@ import scala.language.unsafeNulls import dotty.tools.dotc.config.PathResolver.Defaults import dotty.tools.dotc.config.Settings.{Setting, SettingGroup} +import dotty.tools.dotc.config.SourceVersion import dotty.tools.dotc.core.Contexts._ import dotty.tools.dotc.rewrites.Rewrites import dotty.tools.io.{AbstractFile, Directory, JDK9Reflectors, PlainDirectory} @@ -31,6 +32,9 @@ object ScalaSettings: def supportedScalaReleaseVersions: List[String] = ScalaRelease.values.toList.map(_.show) + def supportedSourceVersions: List[String] = + SourceVersion.values.toList.map(_.toString) + def defaultClasspath: String = sys.env.getOrElse("CLASSPATH", ".") def defaultPageWidth: Int = { @@ -51,7 +55,7 @@ trait AllScalaSettings extends CommonScalaSettings, PluginSettings, VerboseSetti /* Path related settings */ val semanticdbTarget: Setting[String] = PathSetting("-semanticdb-target", "Specify an alternative output directory for SemanticDB files.", "") - val source: Setting[String] = ChoiceSetting("-source", "source version", "source version", List("3.0", "3.1", "future", "3.0-migration", "future-migration"), "3.0", aliases = List("--source")) + val source: Setting[String] = ChoiceSetting("-source", "source version", "source version", ScalaSettings.supportedSourceVersions, SourceVersion.defaultSourceVersion.toString, aliases = List("--source")) val uniqid: Setting[Boolean] = BooleanSetting("-uniqid", "Uniquely tag all identifiers in debugging output.", aliases = List("--unique-id")) val rewrite: Setting[Option[Rewrites]] = OptionSetting[Rewrites]("-rewrite", "When used in conjunction with a `...-migration` source version, rewrites sources to migrate to new version.", aliases = List("--rewrite")) val fromTasty: Setting[Boolean] = BooleanSetting("-from-tasty", "Compile classes from tasty files. The arguments are .tasty or .jar files.", aliases = List("--from-tasty")) diff --git a/compiler/src/dotty/tools/dotc/config/SourceVersion.scala b/compiler/src/dotty/tools/dotc/config/SourceVersion.scala index 4c61ddd036ae..0d84562ea662 100644 --- a/compiler/src/dotty/tools/dotc/config/SourceVersion.scala +++ b/compiler/src/dotty/tools/dotc/config/SourceVersion.scala @@ -6,7 +6,9 @@ import core.Decorators.* import util.Property enum SourceVersion: - case `3.0-migration`, `3.0`, `3.1`, `3.2`, `future-migration`, `future` + case `3.0-migration`, `3.0`, `3.1` // Note: do not add `3.1-migration` here, 3.1 is the same language as 3.0. + case `3.2-migration`, `3.2` + case `future-migration`, `future` val isMigrating: Boolean = toString.endsWith("-migration") @@ -16,6 +18,7 @@ enum SourceVersion: def isAtLeast(v: SourceVersion) = stable.ordinal >= v.ordinal object SourceVersion extends Property.Key[SourceVersion]: + def defaultSourceVersion = `3.0` /** language versions that may appear in a language import, are deprecated, but not removed from the standard library. */ val illegalSourceVersionNames = List("3.1-migration").map(_.toTermName) diff --git a/compiler/src/dotty/tools/dotc/report.scala b/compiler/src/dotty/tools/dotc/report.scala index 94a7b4f318fa..3591c4e1a915 100644 --- a/compiler/src/dotty/tools/dotc/report.scala +++ b/compiler/src/dotty/tools/dotc/report.scala @@ -67,8 +67,7 @@ object report: error(ex.toMessage, pos, sticky = true) if ctx.settings.YdebugTypeError.value then ex.printStackTrace() - def errorOrMigrationWarning(msg: Message, pos: SrcPos = NoSourcePosition, - from: SourceVersion)(using Context): Unit = + def errorOrMigrationWarning(msg: Message, pos: SrcPos = NoSourcePosition, from: SourceVersion)(using Context): Unit = if sourceVersion.isAtLeast(from) then if sourceVersion.isMigrating && sourceVersion.ordinal <= from.ordinal then migrationWarning(msg, pos) else error(msg, pos) diff --git a/compiler/test/dotty/tools/dotc/CompilationTests.scala b/compiler/test/dotty/tools/dotc/CompilationTests.scala index c8082069c28f..52532a17dcbd 100644 --- a/compiler/test/dotty/tools/dotc/CompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/CompilationTests.scala @@ -38,7 +38,7 @@ class CompilationTests { compileFilesInDir("tests/pos-special/spec-t5545", defaultOptions), compileFilesInDir("tests/pos-special/strawman-collections", allowDeepSubtypes), compileFilesInDir("tests/pos-special/isInstanceOf", allowDeepSubtypes.and("-Xfatal-warnings")), - compileFilesInDir("tests/new", defaultOptions.and("-source", "3.1")), // just to see whether 3.1 works + compileFilesInDir("tests/new", defaultOptions.and("-source", "3.2")), // just to see whether 3.2 works compileFilesInDir("tests/pos-scala2", scala2CompatMode), compileFilesInDir("tests/pos-custom-args/erased", defaultOptions.and("-language:experimental.erasedDefinitions")), compileFilesInDir("tests/pos", defaultOptions.and("-Ysafe-init")), diff --git a/library/src/scala/runtime/stdLibPatches/language.scala b/library/src/scala/runtime/stdLibPatches/language.scala index 683155fb0e48..2be4861b4cc2 100644 --- a/library/src/scala/runtime/stdLibPatches/language.scala +++ b/library/src/scala/runtime/stdLibPatches/language.scala @@ -165,19 +165,33 @@ object language: @compileTimeOnly("`3.1` can only be used at compile time in import statements") object `3.1` -/* This can be added when we go to 3.2 /** Set source version to 3.2-migration. * - * @see [[https://scalacenter.github.io/scala-3-migration-guide/docs/scala-3-migration-mode]] + * @see [[https://docs.scala-lang.org/scala3/guides/migration/compatibility-intro.html]] */ @compileTimeOnly("`3.2-migration` can only be used at compile time in import statements") object `3.2-migration` /** Set source version to 3.2 * - * @see [[https://scalacenter.github.io/scala-3-migration-guide/docs/scala-3-migration-mode]] + * @see [[https://docs.scala-lang.org/scala3/guides/migration/compatibility-intro.html]] */ @compileTimeOnly("`3.2` can only be used at compile time in import statements") object `3.2` + +/* This can be added when we go to 3.3 + /** Set source version to 3.3-migration. + * + * @see [[https://docs.scala-lang.org/scala3/guides/migration/compatibility-intro.html]] + */ + @compileTimeOnly("`3.3-migration` can only be used at compile time in import statements") + object `3.3-migration` + + /** Set source version to 3.3 + * + * @see [[https://docs.scala-lang.org/scala3/guides/migration/compatibility-intro.html]] + */ + @compileTimeOnly("`3.3` can only be used at compile time in import statements") + object `3.3` */ end language diff --git a/tests/pos/source-import-3-2-migration.scala b/tests/pos/source-import-3-2-migration.scala new file mode 100644 index 000000000000..4d5e0957298e --- /dev/null +++ b/tests/pos/source-import-3-2-migration.scala @@ -0,0 +1 @@ +import language.`3.2-migration` diff --git a/tests/pos/source-import-3-2.scala b/tests/pos/source-import-3-2.scala new file mode 100644 index 000000000000..3bdf8d028865 --- /dev/null +++ b/tests/pos/source-import-3-2.scala @@ -0,0 +1 @@ +import language.`3.2` From bc459d22f6a9182a66021a93158cae1b2139baa0 Mon Sep 17 00:00:00 2001 From: Tom Grigg Date: Mon, 4 Apr 2022 17:04:06 -0700 Subject: [PATCH 03/12] Set default source version to 3.2 --- compiler/src/dotty/tools/dotc/config/SourceVersion.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/config/SourceVersion.scala b/compiler/src/dotty/tools/dotc/config/SourceVersion.scala index 0d84562ea662..545e2f2d9b42 100644 --- a/compiler/src/dotty/tools/dotc/config/SourceVersion.scala +++ b/compiler/src/dotty/tools/dotc/config/SourceVersion.scala @@ -18,7 +18,7 @@ enum SourceVersion: def isAtLeast(v: SourceVersion) = stable.ordinal >= v.ordinal object SourceVersion extends Property.Key[SourceVersion]: - def defaultSourceVersion = `3.0` + def defaultSourceVersion = `3.2` /** language versions that may appear in a language import, are deprecated, but not removed from the standard library. */ val illegalSourceVersionNames = List("3.1-migration").map(_.toTermName) From 2964880f3f12061db8e1a235c5f4332e2e4e289c Mon Sep 17 00:00:00 2001 From: Tom Grigg Date: Mon, 4 Apr 2022 13:26:53 -0700 Subject: [PATCH 04/12] Introduce `gradualErrorOrMigrationWarning` --- compiler/src/dotty/tools/dotc/report.scala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/src/dotty/tools/dotc/report.scala b/compiler/src/dotty/tools/dotc/report.scala index 3591c4e1a915..5addb11f1a3c 100644 --- a/compiler/src/dotty/tools/dotc/report.scala +++ b/compiler/src/dotty/tools/dotc/report.scala @@ -72,6 +72,10 @@ object report: if sourceVersion.isMigrating && sourceVersion.ordinal <= from.ordinal then migrationWarning(msg, pos) else error(msg, pos) + def gradualErrorOrMigrationWarning(msg: Message, pos: SrcPos = NoSourcePosition, warnFrom: SourceVersion, errorFrom: SourceVersion)(using Context): Unit = + if sourceVersion.isAtLeast(errorFrom) then errorOrMigrationWarning(msg, pos, errorFrom) + else if sourceVersion.isAtLeast(warnFrom) then warning(msg, pos) + def restrictionError(msg: Message, pos: SrcPos = NoSourcePosition)(using Context): Unit = error(msg.mapMsg("Implementation restriction: " + _), pos) From 0bddf1ba72f66b53770f7c9f17df2a5c1d5f1dbe Mon Sep 17 00:00:00 2001 From: Tom Grigg Date: Thu, 7 Apr 2022 13:14:07 -0700 Subject: [PATCH 05/12] Emit strict pattern binding warnings by default Emit warnings by default for refutable pattern bindings. Keep the existing desugaring of for generators (using `withFilter`). In the future, the warnings will become errors, and `case` will be required to get filtering for generators. --- .../src/dotty/tools/dotc/ast/Desugar.scala | 14 +-- compiler/src/dotty/tools/dotc/ast/untpd.scala | 3 +- .../dotty/tools/dotc/parsing/Parsers.scala | 7 +- .../src/dotty/tools/dotc/typer/Checking.scala | 14 +-- .../src/dotty/tools/dotc/typer/Typer.scala | 2 +- .../dotty/tools/dotc/CompilationTests.scala | 5 +- .../changed-features/pattern-bindings.md | 10 +- .../fatal-warnings}/filtering-fors.scala | 0 .../strict-pattern-bindings-3.2.scala | 36 ++++++ .../fatal-warnings}/unchecked-patterns.scala | 0 .../refutable-pattern-binding-messages.check | 12 +- .../refutable-pattern-binding-messages.scala | 2 +- ...trict-pattern-bindings-3.0-migration.scala | 36 ++++++ .../strict-pattern-bindings-3.1.scala | 36 ++++++ tests/run-custom-args/fors.check | 46 ------- tests/run-custom-args/fors.scala | 117 ------------------ tests/run/fors.check | 18 +++ tests/run/fors.scala | 41 +++++- 18 files changed, 197 insertions(+), 202 deletions(-) rename tests/{neg-strict => neg-custom-args/fatal-warnings}/filtering-fors.scala (100%) create mode 100644 tests/neg-custom-args/fatal-warnings/strict-pattern-bindings-3.2.scala rename tests/{neg-strict => neg-custom-args/fatal-warnings}/unchecked-patterns.scala (100%) create mode 100644 tests/pos-special/fatal-warnings/strict-pattern-bindings-3.0-migration.scala create mode 100644 tests/pos-special/fatal-warnings/strict-pattern-bindings-3.1.scala delete mode 100644 tests/run-custom-args/fors.check delete mode 100644 tests/run-custom-args/fors.scala diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index ca5ae257ec41..c49246858f5c 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -1553,7 +1553,7 @@ object desugar { Function(derivedValDef(gen.pat, named, tpt, EmptyTree, Modifiers(Param)) :: Nil, body) case _ => val matchCheckMode = - if (gen.checkMode == GenCheckMode.Check) MatchCheck.IrrefutableGenFrom + if (gen.checkMode == GenCheckMode.Check || gen.checkMode == GenCheckMode.CheckAndFilter) MatchCheck.IrrefutableGenFrom else MatchCheck.None makeCaseLambda(CaseDef(gen.pat, EmptyTree, body) :: Nil, matchCheckMode) } @@ -1640,13 +1640,11 @@ object desugar { case IdPattern(_) => true case _ => false - def needsNoFilter(gen: GenFrom): Boolean = - if (gen.checkMode == GenCheckMode.FilterAlways) // pattern was prefixed by `case` - false - else - gen.checkMode != GenCheckMode.FilterNow - || isVarBinding(gen.pat) - || isIrrefutable(gen.pat, gen.expr) + def needsNoFilter(gen: GenFrom): Boolean = gen.checkMode match + case GenCheckMode.FilterAlways => false // pattern was prefixed by `case` + case GenCheckMode.FilterNow | GenCheckMode.CheckAndFilter => isVarBinding(gen.pat) || isIrrefutable(gen.pat, gen.expr) + case GenCheckMode.Check => true + case GenCheckMode.Ignore => true /** rhs.name with a pattern filter on rhs unless `pat` is irrefutable when * matched against `rhs`. diff --git a/compiler/src/dotty/tools/dotc/ast/untpd.scala b/compiler/src/dotty/tools/dotc/ast/untpd.scala index 7d417b023c14..2decfd3c0479 100644 --- a/compiler/src/dotty/tools/dotc/ast/untpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/untpd.scala @@ -168,7 +168,8 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { enum GenCheckMode { case Ignore // neither filter nor check since filtering was done before case Check // check that pattern is irrefutable - case FilterNow // filter out non-matching elements since we are not yet in 3.x + case CheckAndFilter // both check and filter (transitional period starting with 3.2) + case FilterNow // filter out non-matching elements if we are not in 3.2 or later case FilterAlways // filter out non-matching elements since pattern is prefixed by `case` } diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index f59b73491819..e42da990c742 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -2512,9 +2512,10 @@ object Parsers { def generatorRest(pat: Tree, casePat: Boolean): GenFrom = atSpan(startOffset(pat), accept(LARROW)) { val checkMode = - if (casePat) GenCheckMode.FilterAlways - else if sourceVersion.isAtLeast(future) then GenCheckMode.Check - else GenCheckMode.FilterNow // filter for now, to keep backwards compat + if casePat then GenCheckMode.FilterAlways + else if sourceVersion.isAtLeast(`3.2`) then GenCheckMode.CheckAndFilter + else if sourceVersion.isAtLeast(`future`) then GenCheckMode.Check + else GenCheckMode.FilterNow // filter on source version < 3.2, for backward compat GenFrom(pat, subExpr(), checkMode) } diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index 5f0abaf8904d..c3e9c0fbe560 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -835,23 +835,24 @@ trait Checking { case NonConforming => sel.srcPos case RefutableExtractor => pat.source.atSpan(pat.span union sel.span) else pat.srcPos - def rewriteMsg = Message.rewriteNotice("This patch", `future-migration`) - report.warning( + def rewriteMsg = Message.rewriteNotice("This patch", `3.2-migration`) + report.gradualErrorOrMigrationWarning( em"""$message | |If $usage is intentional, this can be communicated by $fix, |which $addendum.$rewriteMsg""", - pos) + pos, warnFrom = `3.2`, errorFrom = `future`) false } def check(pat: Tree, pt: Type): Boolean = (pt <:< pat.tpe) || fail(pat, pt, Reason.NonConforming) def recur(pat: Tree, pt: Type): Boolean = - !sourceVersion.isAtLeast(future) || // only for 3.x for now since mitigations work only after this PR - pt.hasAnnotation(defn.UncheckedAnnot) || { + !sourceVersion.isAtLeast(`3.2`) + || pt.hasAnnotation(defn.UncheckedAnnot) + || { patmatch.println(i"check irrefutable $pat: ${pat.tpe} against $pt") - pat match { + pat match case Bind(_, pat1) => recur(pat1, pt) case UnApply(fn, _, pats) => @@ -869,7 +870,6 @@ trait Checking { case _ => check(pat, pt) } - } recur(pat, pt) } diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index a13ea88f14e7..7ece68cea480 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1619,7 +1619,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer tree.selector.removeAttachment(desugar.CheckIrrefutable) match { case Some(checkMode) if !sel.tpe.hasAnnotation(defn.UncheckedAnnot) => val isPatDef = checkMode == desugar.MatchCheck.IrrefutablePatDef - if !checkIrrefutable(sel, pat, isPatDef) && sourceVersion == `future-migration` then + if !checkIrrefutable(sel, pat, isPatDef) && sourceVersion.isAtLeast(`3.2`) && sourceVersion.isMigrating then if isPatDef then uncheckedBrackets(tree.selector) match case None => patch(Span(tree.selector.span.end), ": @unchecked") diff --git a/compiler/test/dotty/tools/dotc/CompilationTests.scala b/compiler/test/dotty/tools/dotc/CompilationTests.scala index 52532a17dcbd..dd1213514d82 100644 --- a/compiler/test/dotty/tools/dotc/CompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/CompilationTests.scala @@ -73,8 +73,8 @@ class CompilationTests { aggregateTests( compileFile("tests/rewrites/rewrites.scala", scala2CompatMode.and("-rewrite", "-indent")), compileFile("tests/rewrites/rewrites3x.scala", defaultOptions.and("-rewrite", "-source", "future-migration")), - compileFile("tests/rewrites/filtering-fors.scala", defaultOptions.and("-rewrite", "-source", "future-migration")), - compileFile("tests/rewrites/refutable-pattern-bindings.scala", defaultOptions.and("-rewrite", "-source", "future-migration")), + compileFile("tests/rewrites/filtering-fors.scala", defaultOptions.and("-rewrite", "-source", "3.2-migration")), + compileFile("tests/rewrites/refutable-pattern-bindings.scala", defaultOptions.and("-rewrite", "-source", "3.2-migration")), compileFile("tests/rewrites/i8982.scala", defaultOptions.and("-indent", "-rewrite")), compileFile("tests/rewrites/i9632.scala", defaultOptions.and("-indent", "-rewrite")), compileFile("tests/rewrites/i11895.scala", defaultOptions.and("-indent", "-rewrite")), @@ -203,7 +203,6 @@ class CompilationTests { compileFile("tests/run-custom-args/typeclass-derivation1.scala", defaultOptions.without(yCheckOptions: _*)), compileFile("tests/run-custom-args/tuple-cons.scala", allowDeepSubtypes), compileFile("tests/run-custom-args/i5256.scala", allowDeepSubtypes), - compileFile("tests/run-custom-args/fors.scala", defaultOptions.and("-source", "future")), compileFile("tests/run-custom-args/no-useless-forwarders.scala", defaultOptions and "-Xmixin-force-forwarders:false"), compileFile("tests/run-custom-args/defaults-serizaliable-no-forwarders.scala", defaultOptions and "-Xmixin-force-forwarders:false"), compileFilesInDir("tests/run-custom-args/erased", defaultOptions.and("-language:experimental.erasedDefinitions")), diff --git a/docs/_docs/reference/changed-features/pattern-bindings.md b/docs/_docs/reference/changed-features/pattern-bindings.md index 2c8d1c10ceae..b7b7432e7817 100644 --- a/docs/_docs/reference/changed-features/pattern-bindings.md +++ b/docs/_docs/reference/changed-features/pattern-bindings.md @@ -7,7 +7,7 @@ movedTo: https://docs.scala-lang.org/scala3/reference/changed-features/pattern-b In Scala 2, pattern bindings in `val` definitions and `for` expressions are loosely typed. Potentially failing matches are still accepted at compile-time, but may influence the program's runtime behavior. -From Scala 3.1 on, type checking rules will be tightened so that warnings are reported at compile-time instead. +From Scala 3.2 on, type checking rules will be tightened so that warnings are reported at compile-time instead. ## Bindings in Pattern Definitions @@ -16,7 +16,7 @@ val xs: List[Any] = List(1, 2, 3) val (x: String) :: _ = xs // error: pattern's type String is more specialized // than the right-hand side expression's type Any ``` -This code gives a compile-time warning in Scala 3.1 (and also in Scala 3.0 under the `-source future` setting) whereas it will fail at runtime with a `ClassCastException` in Scala 2. In Scala 3.1, a pattern binding is only allowed if the pattern is _irrefutable_, that is, if the right-hand side's type conforms to the pattern's type. For instance, the following is OK: +This code gives a compile-time warning in Scala 3.2 (and also earlier Scala 3.x under the `-source future` setting) whereas it will fail at runtime with a `ClassCastException` in Scala 2. In Scala 3.2, a pattern binding is only allowed if the pattern is _irrefutable_, that is, if the right-hand side's type conforms to the pattern's type. For instance, the following is OK: ```scala val pair = (1, true) val (x, y) = pair @@ -25,7 +25,7 @@ Sometimes one wants to decompose data anyway, even though the pattern is refutab ```scala val first :: rest = elems // error ``` -This works in Scala 2. In fact it is a typical use case for Scala 2's rules. But in Scala 3.1 it will give a warning. One can avoid the warning by marking the right-hand side with an [`@unchecked`](https://scala-lang.org/api/3.x/scala/unchecked.html) annotation: +This works in Scala 2. In fact it is a typical use case for Scala 2's rules. But in Scala 3.2 it will give a warning. One can avoid the warning by marking the right-hand side with an [`@unchecked`](https://scala-lang.org/api/3.x/scala/unchecked.html) annotation: ```scala val first :: rest = elems: @unchecked // OK ``` @@ -40,7 +40,7 @@ val elems: List[Any] = List((1, 2), "hello", (3, 4)) for (x, y) <- elems yield (y, x) // error: pattern's type (Any, Any) is more specialized // than the right-hand side expression's type Any ``` -This code gives a compile-time warning in Scala 3.1 whereas in Scala 2 the list `elems` +This code gives a compile-time warning in Scala 3.2 whereas in Scala 2 the list `elems` is filtered to retain only the elements of tuple type that match the pattern `(x, y)`. The filtering functionality can be obtained in Scala 3 by prefixing the pattern with `case`: ```scala @@ -56,4 +56,4 @@ Generator ::= [‘case’] Pattern1 ‘<-’ Expr ## Migration -The new syntax is supported in Scala 3.0. However, to enable smooth cross compilation between Scala 2 and Scala 3, the changed behavior and additional type checks are only enabled under the `-source future` setting. They will be enabled by default in version 3.1 of the language. +The new syntax is supported in Scala 3.0. However, to enable smooth cross compilation between Scala 2 and Scala 3, the changed behavior and additional type checks are only enabled under the `-source future` setting. They will be enabled by default in version 3.2 of the language. diff --git a/tests/neg-strict/filtering-fors.scala b/tests/neg-custom-args/fatal-warnings/filtering-fors.scala similarity index 100% rename from tests/neg-strict/filtering-fors.scala rename to tests/neg-custom-args/fatal-warnings/filtering-fors.scala diff --git a/tests/neg-custom-args/fatal-warnings/strict-pattern-bindings-3.2.scala b/tests/neg-custom-args/fatal-warnings/strict-pattern-bindings-3.2.scala new file mode 100644 index 000000000000..23c8af3f0f19 --- /dev/null +++ b/tests/neg-custom-args/fatal-warnings/strict-pattern-bindings-3.2.scala @@ -0,0 +1,36 @@ +// These tests should fail under -Xfatal-warnings with source version source version 3.2 or later +import language.`3.2` + +object Test: + // from filtering-fors.scala + val xs: List[AnyRef] = ??? + + for ((x: String) <- xs) do () // error + for (y@ (x: String) <- xs) do () // error + for ((x, y) <- xs) do () // error + + for ((x: String) <- xs if x.isEmpty) do () // error + for ((x: String) <- xs; y = x) do () // error + for ((x: String) <- xs; (y, z) <- xs) do () // error // error + for (case (x: String) <- xs; (y, z) <- xs) do () // error + for ((x: String) <- xs; case (y, z) <- xs) do () // error + + val pairs: List[AnyRef] = List((1, 2), "hello", (3, 4)) + for ((x, y) <- pairs) yield (y, x) // error + + // from unchecked-patterns.scala + val y :: ys = List(1, 2, 3) // error + val (1, c) = (1, 2) // error + val 1 *: cs = 1 *: Tuple() // error + + val (_: Int | _: AnyRef) = ??? : AnyRef // error + + val 1 = 2 // error + + object Positive { def unapply(i: Int): Option[Int] = Some(i).filter(_ > 0) } + object Always1 { def unapply(i: Int): Some[Int] = Some(i) } + object Pair { def unapply(t: (Int, Int)): t.type = t } + object Triple { def unapply(t: (Int, Int, Int)): (Int, Int, Int) = t } + + val Positive(p) = 5 // error + val Some(s1) = Option(1) // error diff --git a/tests/neg-strict/unchecked-patterns.scala b/tests/neg-custom-args/fatal-warnings/unchecked-patterns.scala similarity index 100% rename from tests/neg-strict/unchecked-patterns.scala rename to tests/neg-custom-args/fatal-warnings/unchecked-patterns.scala diff --git a/tests/neg/refutable-pattern-binding-messages.check b/tests/neg/refutable-pattern-binding-messages.check index 6cf67466d507..5a9d85fd4447 100644 --- a/tests/neg/refutable-pattern-binding-messages.check +++ b/tests/neg/refutable-pattern-binding-messages.check @@ -5,7 +5,7 @@ | | If this usage is intentional, this can be communicated by adding the `case` keyword before the full pattern, | which will result in a filtering for expression (using `withFilter`). - | This patch can be rewritten automatically under -rewrite -source future-migration. + | This patch can be rewritten automatically under -rewrite -source 3.2-migration. -- Error: tests/neg/refutable-pattern-binding-messages.scala:11:11 ----------------------------------------------------- 11 | for ((x: String) <- xs) do () // error: pattern type more specialized | ^^^^^^ @@ -13,7 +13,7 @@ | | If the narrowing is intentional, this can be communicated by adding the `case` keyword before the full pattern, | which will result in a filtering for expression (using `withFilter`). - | This patch can be rewritten automatically under -rewrite -source future-migration. + | This patch can be rewritten automatically under -rewrite -source 3.2-migration. -- Error: tests/neg/refutable-pattern-binding-messages.scala:15:13 ----------------------------------------------------- 15 | for none @ None <- ys do () // error: pattern type does not match | ^^^^ @@ -21,7 +21,7 @@ | | If the narrowing is intentional, this can be communicated by adding the `case` keyword before the full pattern, | which will result in a filtering for expression (using `withFilter`). - | This patch can be rewritten automatically under -rewrite -source future-migration. + | This patch can be rewritten automatically under -rewrite -source 3.2-migration. -- Error: tests/neg/refutable-pattern-binding-messages.scala:5:14 ------------------------------------------------------ 5 | val Positive(p) = 5 // error: refutable extractor | ^^^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ | | If this usage is intentional, this can be communicated by adding `: @unchecked` after the expression, | which may result in a MatchError at runtime. - | This patch can be rewritten automatically under -rewrite -source future-migration. + | This patch can be rewritten automatically under -rewrite -source 3.2-migration. -- Error: tests/neg/refutable-pattern-binding-messages.scala:10:20 ----------------------------------------------------- 10 | val i :: is = List(1, 2, 3) // error: pattern type more specialized | ^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ | | If the narrowing is intentional, this can be communicated by adding `: @unchecked` after the expression, | which may result in a MatchError at runtime. - | This patch can be rewritten automatically under -rewrite -source future-migration. + | This patch can be rewritten automatically under -rewrite -source 3.2-migration. -- Error: tests/neg/refutable-pattern-binding-messages.scala:16:10 ----------------------------------------------------- 16 | val 1 = 2 // error: pattern type does not match | ^ @@ -45,4 +45,4 @@ | | If the narrowing is intentional, this can be communicated by adding `: @unchecked` after the expression, | which may result in a MatchError at runtime. - | This patch can be rewritten automatically under -rewrite -source future-migration. + | This patch can be rewritten automatically under -rewrite -source 3.2-migration. diff --git a/tests/neg/refutable-pattern-binding-messages.scala b/tests/neg/refutable-pattern-binding-messages.scala index 202cdff0ec99..97ce61503a2b 100644 --- a/tests/neg/refutable-pattern-binding-messages.scala +++ b/tests/neg/refutable-pattern-binding-messages.scala @@ -1,4 +1,4 @@ -// scalac: -source:future -Werror +// scalac: -Werror object Test { // refutable extractor object Positive { def unapply(i: Int): Option[Int] = Some(i).filter(_ > 0) } diff --git a/tests/pos-special/fatal-warnings/strict-pattern-bindings-3.0-migration.scala b/tests/pos-special/fatal-warnings/strict-pattern-bindings-3.0-migration.scala new file mode 100644 index 000000000000..bab804d81fac --- /dev/null +++ b/tests/pos-special/fatal-warnings/strict-pattern-bindings-3.0-migration.scala @@ -0,0 +1,36 @@ +// These tests should pass under -Xfatal-warnings with source version less than 3.2 +import language.`3.0-migration` + +object Test: + // from filtering-fors.scala + val xs: List[AnyRef] = ??? + + for ((x: String) <- xs) do () + for (y@ (x: String) <- xs) do () + for ((x, y) <- xs) do () + + for ((x: String) <- xs if x.isEmpty) do () + for ((x: String) <- xs; y = x) do () + for ((x: String) <- xs; (y, z) <- xs) do () + for (case (x: String) <- xs; (y, z) <- xs) do () + for ((x: String) <- xs; case (y, z) <- xs) do () + + val pairs: List[AnyRef] = List((1, 2), "hello", (3, 4)) + for ((x, y) <- pairs) yield (y, x) + + // from unchecked-patterns.scala + val y :: ys = List(1, 2, 3) + val (1, c) = (1, 2) + val 1 *: cs = 1 *: Tuple() + + val (_: Int | _: AnyRef) = ??? : AnyRef + + val 1 = 2 + + object Positive { def unapply(i: Int): Option[Int] = Some(i).filter(_ > 0) } + object Always1 { def unapply(i: Int): Some[Int] = Some(i) } + object Pair { def unapply(t: (Int, Int)): t.type = t } + object Triple { def unapply(t: (Int, Int, Int)): (Int, Int, Int) = t } + + val Positive(p) = 5 + val Some(s1) = Option(1) diff --git a/tests/pos-special/fatal-warnings/strict-pattern-bindings-3.1.scala b/tests/pos-special/fatal-warnings/strict-pattern-bindings-3.1.scala new file mode 100644 index 000000000000..8ed183dd1209 --- /dev/null +++ b/tests/pos-special/fatal-warnings/strict-pattern-bindings-3.1.scala @@ -0,0 +1,36 @@ +// These tests should pass under -Xfatal-warnings with source version less than 3.2 +import language.`3.1` + +object Test: + // from filtering-fors.scala + val xs: List[AnyRef] = ??? + + for ((x: String) <- xs) do () + for (y@ (x: String) <- xs) do () + for ((x, y) <- xs) do () + + for ((x: String) <- xs if x.isEmpty) do () + for ((x: String) <- xs; y = x) do () + for ((x: String) <- xs; (y, z) <- xs) do () + for (case (x: String) <- xs; (y, z) <- xs) do () + for ((x: String) <- xs; case (y, z) <- xs) do () + + val pairs: List[AnyRef] = List((1, 2), "hello", (3, 4)) + for ((x, y) <- pairs) yield (y, x) + + // from unchecked-patterns.scala + val y :: ys = List(1, 2, 3) + val (1, c) = (1, 2) + val 1 *: cs = 1 *: Tuple() + + val (_: Int | _: AnyRef) = ??? : AnyRef + + val 1 = 2 + + object Positive { def unapply(i: Int): Option[Int] = Some(i).filter(_ > 0) } + object Always1 { def unapply(i: Int): Some[Int] = Some(i) } + object Pair { def unapply(t: (Int, Int)): t.type = t } + object Triple { def unapply(t: (Int, Int, Int)): (Int, Int, Int) = t } + + val Positive(p) = 5 + val Some(s1) = Option(1) diff --git a/tests/run-custom-args/fors.check b/tests/run-custom-args/fors.check deleted file mode 100644 index a8c7dfd6c4bd..000000000000 --- a/tests/run-custom-args/fors.check +++ /dev/null @@ -1,46 +0,0 @@ - -testOld -1 2 3 -2 -2 -3 -1 2 3 -1 2 3 -0 1 2 3 4 5 6 7 8 9 -0 2 4 6 8 -0 2 4 6 8 -a b c -b c -b c - -testNew -3 -1 2 3 -1 2 3 -0 1 2 3 4 5 6 7 8 9 -0 2 4 6 8 -0 2 4 6 8 -0 2 4 6 8 -0 2 4 6 8 -0 2 4 6 8 -0 2 4 6 8 -0 2 4 6 8 -a b c - -testFiltering -hello world -hello world -hello world -1~2 3~4 -(empty) -hello world -hello/1~2 hello/3~4 /1~2 /3~4 world/1~2 world/3~4 -(2,1) (4,3) -hello world -hello world -hello world -1~2 3~4 -(empty) -hello world -hello/1~2 hello/3~4 /1~2 /3~4 world/1~2 world/3~4 -(2,1) (4,3) diff --git a/tests/run-custom-args/fors.scala b/tests/run-custom-args/fors.scala deleted file mode 100644 index d8f76473f773..000000000000 --- a/tests/run-custom-args/fors.scala +++ /dev/null @@ -1,117 +0,0 @@ -//############################################################################ -// for-comprehensions (old and new syntax) -//############################################################################ - -//############################################################################ - -object Test extends App { - val xs = List(1, 2, 3) - val ys = List(Symbol("a"), Symbol("b"), Symbol("c")) - - def it = 0 until 10 - - val ar = "abc".toCharArray - - /////////////////// old syntax /////////////////// - - def testOld(): Unit = { - println("\ntestOld") - - // lists - for (x <- xs) print(x + " "); println() - for (x <- xs; - if x % 2 == 0) print(x + " "); println() - for {x <- xs - if x % 2 == 0} print(x + " "); println() - var n = 0 - for (_ <- xs) n += 1; println(n) - for ((x, y) <- xs zip ys) print(x + " "); println() - for (p @ (x, y) <- xs zip ys) print(p._1 + " "); println() - - // iterators - for (x <- it) print(x + " "); println() - for (x <- it; - if x % 2 == 0) print(x + " "); println() - for {x <- it - if x % 2 == 0} print(x + " "); println() - - // arrays - for (x <- ar) print(x + " "); println() - for (x <- ar; - if x.toInt > 97) print(x + " "); println() - for {x <- ar - if x.toInt > 97} print(x + " "); println() - - } - - /////////////////// new syntax /////////////////// - - def testNew(): Unit = { - println("\ntestNew") - - // lists - var n = 0 - for (_ <- xs) n += 1; println(n) - for ((x, y) <- xs zip ys) print(x + " "); println() - for (p @ (x, y) <- xs zip ys) print(p._1 + " "); println() - - // iterators - for (x <- it) print(x + " "); println() - for (x <- it if x % 2 == 0) print(x + " "); println() - for (x <- it; if x % 2 == 0) print(x + " "); println() - for (x <- it; - if x % 2 == 0) print(x + " "); println() - for (x <- it - if x % 2 == 0) print(x + " "); println() - for {x <- it - if x % 2 == 0} print(x + " "); println() - for (x <- it; - y = 2 - if x % y == 0) print(x + " "); println() - for {x <- it - y = 2 - if x % y == 0} print(x + " "); println() - - // arrays - for (x <- ar) print(x + " "); println() - - } - - /////////////////// filtering with case /////////////////// - - def testFiltering(): Unit = { - println("\ntestFiltering") - - val xs: List[Any] = List((1, 2), "hello", (3, 4), "", "world") - - for (case x: String <- xs) do print(s"$x "); println() - for (case (x: String) <- xs) do print(s"$x "); println() - for (case y@ (x: String) <- xs) do print(s"$y "); println() - - for (case (x, y) <- xs) do print(s"$x~$y "); println() - - for (case (x: String) <- xs if x.isEmpty) do print("(empty)"); println() - for (case (x: String) <- xs; y = x) do print(s"$y "); println() - for (case (x: String) <- xs; case (y, z) <- xs) do print(s"$x/$y~$z "); println() - - for (case (x, y) <- xs) do print(s"${(y, x)} "); println() - - for case x: String <- xs do print(s"$x "); println() - for case (x: String) <- xs do print(s"$x "); println() - for case y@ (x: String) <- xs do print(s"$y "); println() - - for case (x, y) <- xs do print(s"$x~$y "); println() - - for case (x: String) <- xs if x.isEmpty do print("(empty)"); println() - for case (x: String) <- xs; y = x do print(s"$y "); println() - for case (x: String) <- xs; case (y, z) <- xs do print(s"$x/$y~$z "); println() - - for case (x, y) <- xs do print(s"${(y, x)} "); println() - } - - //////////////////////////////////////////////////// - - testOld() - testNew() - testFiltering() -} diff --git a/tests/run/fors.check b/tests/run/fors.check index b459f00b4910..a8c7dfd6c4bd 100644 --- a/tests/run/fors.check +++ b/tests/run/fors.check @@ -26,3 +26,21 @@ testNew 0 2 4 6 8 0 2 4 6 8 a b c + +testFiltering +hello world +hello world +hello world +1~2 3~4 +(empty) +hello world +hello/1~2 hello/3~4 /1~2 /3~4 world/1~2 world/3~4 +(2,1) (4,3) +hello world +hello world +hello world +1~2 3~4 +(empty) +hello world +hello/1~2 hello/3~4 /1~2 /3~4 world/1~2 world/3~4 +(2,1) (4,3) diff --git a/tests/run/fors.scala b/tests/run/fors.scala index 188f60664bbb..d8f76473f773 100644 --- a/tests/run/fors.scala +++ b/tests/run/fors.scala @@ -14,7 +14,7 @@ object Test extends App { /////////////////// old syntax /////////////////// - def testOld: Unit = { + def testOld(): Unit = { println("\ntestOld") // lists @@ -46,7 +46,7 @@ object Test extends App { /////////////////// new syntax /////////////////// - def testNew: Unit = { + def testNew(): Unit = { println("\ntestNew") // lists @@ -77,8 +77,41 @@ object Test extends App { } + /////////////////// filtering with case /////////////////// + + def testFiltering(): Unit = { + println("\ntestFiltering") + + val xs: List[Any] = List((1, 2), "hello", (3, 4), "", "world") + + for (case x: String <- xs) do print(s"$x "); println() + for (case (x: String) <- xs) do print(s"$x "); println() + for (case y@ (x: String) <- xs) do print(s"$y "); println() + + for (case (x, y) <- xs) do print(s"$x~$y "); println() + + for (case (x: String) <- xs if x.isEmpty) do print("(empty)"); println() + for (case (x: String) <- xs; y = x) do print(s"$y "); println() + for (case (x: String) <- xs; case (y, z) <- xs) do print(s"$x/$y~$z "); println() + + for (case (x, y) <- xs) do print(s"${(y, x)} "); println() + + for case x: String <- xs do print(s"$x "); println() + for case (x: String) <- xs do print(s"$x "); println() + for case y@ (x: String) <- xs do print(s"$y "); println() + + for case (x, y) <- xs do print(s"$x~$y "); println() + + for case (x: String) <- xs if x.isEmpty do print("(empty)"); println() + for case (x: String) <- xs; y = x do print(s"$y "); println() + for case (x: String) <- xs; case (y, z) <- xs do print(s"$x/$y~$z "); println() + + for case (x, y) <- xs do print(s"${(y, x)} "); println() + } + //////////////////////////////////////////////////// - testOld - testNew + testOld() + testNew() + testFiltering() } From 46329eec157781b3ed99140f2072e4ecdbb304d9 Mon Sep 17 00:00:00 2001 From: Tom Grigg Date: Tue, 18 Jan 2022 13:12:56 -0800 Subject: [PATCH 06/12] Adapt the codebase to strict pattern binding warnings In order to bootstrap the compiler with the rules now enforced by default by the previous commit. --- .../tools/backend/jvm/BCodeBodyBuilder.scala | 10 +++---- .../tools/backend/jvm/BCodeHelpers.scala | 2 +- .../tools/backend/jvm/BCodeSkelBuilder.scala | 2 +- .../dotty/tools/backend/sjs/JSCodeGen.scala | 28 +++++++++---------- .../tools/backend/sjs/JSExportsGen.scala | 2 +- .../src/dotty/tools/dotc/ast/Desugar.scala | 8 +++--- .../dotty/tools/dotc/ast/MainProxies.scala | 2 +- .../src/dotty/tools/dotc/ast/TreeInfo.scala | 2 +- .../dotty/tools/dotc/ast/TreeTypeMap.scala | 3 +- compiler/src/dotty/tools/dotc/ast/tpd.scala | 2 +- .../dotty/tools/dotc/config/Settings.scala | 2 +- .../dotty/tools/dotc/core/Annotations.scala | 6 ++-- .../tools/dotc/core/ConstraintHandling.scala | 6 ++-- .../tools/dotc/core/OrderingConstraint.scala | 2 +- .../dotty/tools/dotc/core/TypeComparer.scala | 10 +++---- .../dotty/tools/dotc/core/TypeErasure.scala | 2 +- .../dotc/core/classfile/ClassfileParser.scala | 2 +- .../tools/dotc/core/tasty/TastyPickler.scala | 2 +- .../tools/dotc/core/tasty/TreePickler.scala | 8 +++--- .../core/unpickleScala2/Scala2Unpickler.scala | 4 +-- .../tools/dotc/interactive/Interactive.scala | 2 +- .../dotty/tools/dotc/parsing/Parsers.scala | 4 +-- .../dotty/tools/dotc/plugins/Plugins.scala | 2 +- .../tools/dotc/printing/PlainPrinter.scala | 2 +- .../tools/dotc/printing/RefinedPrinter.scala | 2 +- .../tools/dotc/quoted/PickledQuotes.scala | 6 ++-- .../dotty/tools/dotc/reporting/messages.scala | 2 +- .../dotty/tools/dotc/semanticdb/Scala3.scala | 4 +-- .../dotc/transform/ArrayConstructors.scala | 4 +-- .../tools/dotc/transform/Constructors.scala | 2 +- .../tools/dotc/transform/ElimByName.scala | 2 +- .../dotc/transform/ElimOuterSelect.scala | 2 +- .../tools/dotc/transform/ElimRepeated.scala | 6 ++-- .../dotty/tools/dotc/transform/Erasure.scala | 6 ++-- .../tools/dotc/transform/ExpandSAMs.scala | 2 +- .../tools/dotc/transform/ExplicitOuter.scala | 2 +- .../dotc/transform/FullParameterization.scala | 2 +- .../transform/FunctionXXLForwarders.scala | 2 +- .../dotc/transform/GenericSignatures.scala | 2 +- .../dotty/tools/dotc/transform/Memoize.scala | 2 +- .../dotty/tools/dotc/transform/Mixin.scala | 2 +- .../dotc/transform/PCPCheckAndHeal.scala | 4 +-- .../tools/dotc/transform/PatternMatcher.scala | 8 +++--- .../tools/dotc/transform/PickleQuotes.scala | 4 +-- .../tools/dotc/transform/PostTyper.scala | 2 +- .../dotty/tools/dotc/transform/Splicer.scala | 2 +- .../dotty/tools/dotc/transform/Splicing.scala | 2 +- .../tools/dotc/transform/SuperAccessors.scala | 4 +-- .../tools/dotc/transform/TreeChecker.scala | 4 +-- .../dotc/transform/TreeMapWithStages.scala | 2 +- .../dotc/transform/TupleOptimizations.scala | 10 +++---- .../tools/dotc/transform/init/Semantic.scala | 4 +-- .../tools/dotc/transform/patmat/Space.scala | 2 +- .../transform/sjs/AddLocalJSFakeNews.scala | 2 +- .../dotc/transform/sjs/PrepJSInterop.scala | 2 +- .../dotty/tools/dotc/typer/Applications.scala | 6 ++-- .../src/dotty/tools/dotc/typer/Checking.scala | 2 +- .../src/dotty/tools/dotc/typer/Deriving.scala | 2 +- .../src/dotty/tools/dotc/typer/Dynamic.scala | 2 +- .../src/dotty/tools/dotc/typer/Inliner.scala | 8 +++--- .../src/dotty/tools/dotc/typer/Namer.scala | 10 +++---- .../tools/dotc/typer/QuotesAndSplices.scala | 2 +- .../dotty/tools/dotc/typer/RefChecks.scala | 4 +-- .../dotty/tools/dotc/typer/Synthesizer.scala | 2 +- .../dotty/tools/dotc/typer/TypeAssigner.scala | 2 +- .../src/dotty/tools/dotc/typer/Typer.scala | 18 ++++++------ .../dotty/tools/dotc/util/ParsedComment.scala | 2 +- .../tools/repl/CollectTopLevelImports.scala | 2 +- .../quoted/runtime/impl/QuotesImpl.scala | 4 +-- .../runtime/impl/printers/SourceCode.scala | 14 +++++----- library/src/scala/quoted/ExprMap.scala | 4 +-- library/src/scala/quoted/Quotes.scala | 2 +- .../scaladoc/renderers/MemberRenderer.scala | 2 +- .../scaladoc/snippets/SelfTypePrinter.scala | 2 +- .../scaladoc/tasty/ClassLikeSupport.scala | 2 +- .../scaladoc/tasty/comments/wiki/Parser.scala | 2 +- 76 files changed, 156 insertions(+), 155 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala index 7bcc8fcf6b09..3a060f763330 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala @@ -359,7 +359,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { // but I was able to derrive it by reading // AbstractValidatingLambdaMetafactory.validateMetafactoryArgs - val DesugaredSelect(prefix, _) = fun + val DesugaredSelect(prefix, _) = fun: @unchecked genLoad(prefix) } @@ -725,7 +725,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { lineNumber(app) app match { case Apply(_, args) if app.symbol eq defn.newArrayMethod => - val List(elemClaz, Literal(c: Constant), ArrayValue(_, dims)) = args + val List(elemClaz, Literal(c: Constant), ArrayValue(_, dims)) = args: @unchecked generatedType = toTypeKind(c.typeValue) mkArrayConstructorCall(generatedType.asArrayBType, app, dims) @@ -802,7 +802,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { if (invokeStyle.hasInstance) genLoadQualifier(fun) genLoadArguments(args, paramTKs(app)) - val DesugaredSelect(qual, name) = fun // fun is a Select, also checked in genLoadQualifier + val DesugaredSelect(qual, name) = fun: @unchecked // fun is a Select, also checked in genLoadQualifier val isArrayClone = name == nme.clone_ && qual.tpe.widen.isInstanceOf[JavaArrayType] if (isArrayClone) { // Special-case Array.clone, introduced in 36ef60e. The goal is to generate this call @@ -845,7 +845,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { } // end of genApply() private def genArrayValue(av: tpd.JavaSeqLiteral): BType = { - val ArrayValue(tpt, elems) = av + val ArrayValue(tpt, elems) = av: @unchecked lineNumber(av) genArray(elems, tpt) @@ -1530,7 +1530,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder { import ScalaPrimitivesOps.{ ZNOT, ZAND, ZOR, EQ } // lhs and rhs of test - lazy val DesugaredSelect(lhs, _) = fun + lazy val DesugaredSelect(lhs, _) = fun: @unchecked val rhs = if (args.isEmpty) tpd.EmptyTree else args.head // args.isEmpty only for ZNOT def genZandOrZor(and: Boolean): Unit = { diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index f254dea184ed..baa0112a2dbc 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -151,7 +151,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { // sorting ensures nested classes are listed after their enclosing class thus satisfying the Eclipse Java compiler for (nestedClass <- allNestedClasses.sortBy(_.internalName.toString)) { // Extract the innerClassEntry - we know it exists, enclosingNestedClassesChain only returns nested classes. - val Some(e) = nestedClass.innerClassAttributeEntry + val Some(e) = nestedClass.innerClassAttributeEntry: @unchecked jclass.visitInnerClass(e.name, e.outerName, e.innerName, e.flags) } } diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 829b156be428..8227e6a4e88c 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -689,7 +689,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { val origSym = dd.symbol.asTerm val newSym = makeStatifiedDefSymbol(origSym, origSym.name) tpd.DefDef(newSym, { paramRefss => - val selfParamRef :: regularParamRefs = paramRefss.head + val selfParamRef :: regularParamRefs = paramRefss.head: @unchecked val enclosingClass = origSym.owner.asClass new TreeTypeMap( typeMap = _.substThis(enclosingClass, selfParamRef.symbol.termRef) diff --git a/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala b/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala index 45254b1e2325..1413ab2933a0 100644 --- a/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala +++ b/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala @@ -1025,7 +1025,7 @@ class JSCodeGen()(using genCtx: Context) { */ val (primaryTree :: Nil, secondaryTrees) = - constructorTrees.partition(_.symbol.isPrimaryConstructor) + constructorTrees.partition(_.symbol.isPrimaryConstructor): @unchecked val primaryCtor = genPrimaryJSClassCtor(primaryTree) val secondaryCtors = secondaryTrees.map(genSecondaryJSClassCtor(_)) @@ -1106,7 +1106,7 @@ class JSCodeGen()(using genCtx: Context) { private def genPrimaryJSClassCtor(dd: DefDef): PrimaryJSCtor = { val sym = dd.symbol - val Block(stats, _) = dd.rhs + val Block(stats, _) = dd.rhs: @unchecked assert(sym.isPrimaryConstructor, s"called with non-primary ctor: $sym") var jsSuperCall: Option[js.JSSuperConstructorCall] = None @@ -1179,7 +1179,7 @@ class JSCodeGen()(using genCtx: Context) { assert(thisCall.isDefined, i"could not find the this() call in secondary JS constructor at ${dd.sourcePos}:\n${stats.map(_.show).mkString("\n")}") - val Some((targetCtor, ctorArgs)) = thisCall + val Some((targetCtor, ctorArgs)) = thisCall: @unchecked new SplitSecondaryJSCtor(sym, genParamsAndInfo(sym, dd.paramss), beforeThisCall.result(), targetCtor, ctorArgs, afterThisCall.result()) @@ -2139,7 +2139,7 @@ class JSCodeGen()(using genCtx: Context) { */ private def genSuperCall(tree: Apply, isStat: Boolean): js.Tree = { implicit val pos = tree.span - val Apply(fun @ Select(sup @ Super(qual, _), _), args) = tree + val Apply(fun @ Select(sup @ Super(qual, _), _), args) = tree: @unchecked val sym = fun.symbol if (sym == defn.Any_getClass) { @@ -2180,7 +2180,7 @@ class JSCodeGen()(using genCtx: Context) { private def genApplyNew(tree: Apply): js.Tree = { implicit val pos: SourcePosition = tree.sourcePos - val Apply(fun @ Select(New(tpt), nme.CONSTRUCTOR), args) = tree + val Apply(fun @ Select(New(tpt), nme.CONSTRUCTOR), args) = tree: @unchecked val ctor = fun.symbol val tpe = tpt.tpe @@ -2229,7 +2229,7 @@ class JSCodeGen()(using genCtx: Context) { acquireContextualJSClassValue { jsClassValue => implicit val pos: Position = tree.span - val Apply(fun @ Select(New(tpt), _), args) = tree + val Apply(fun @ Select(New(tpt), _), args) = tree: @unchecked val cls = tpt.tpe.typeSymbol val ctor = fun.symbol @@ -2898,7 +2898,7 @@ class JSCodeGen()(using genCtx: Context) { implicit val pos = tree.span - val Apply(fun, args) = tree + val Apply(fun, args) = tree: @unchecked val arrayObj = qualifierOf(fun) val genArray = genExpr(arrayObj) @@ -3167,7 +3167,7 @@ class JSCodeGen()(using genCtx: Context) { private def genJSSuperCall(tree: Apply, isStat: Boolean): js.Tree = { acquireContextualJSClassValue { explicitJSSuperClassValue => implicit val pos = tree.span - val Apply(fun @ Select(sup @ Super(qual, _), _), args) = tree + val Apply(fun @ Select(sup @ Super(qual, _), _), args) = tree: @unchecked val sym = fun.symbol val genReceiver = genExpr(qual) @@ -3242,7 +3242,7 @@ class JSCodeGen()(using genCtx: Context) { /** Gen JS code for a switch-`Match`, which is translated into an IR `js.Match`. */ def genMatch(tree: Tree, isStat: Boolean): js.Tree = { implicit val pos = tree.span - val Match(selector, cases) = tree + val Match(selector, cases) = tree: @unchecked def abortMatch(msg: String): Nothing = throw new FatalError(s"$msg in switch-like pattern match at ${tree.span}: $tree") @@ -3441,7 +3441,7 @@ class JSCodeGen()(using genCtx: Context) { val call = if (isStaticCall) { genApplyStatic(sym, formalCaptures.map(_.ref) ::: actualParams) } else { - val thisCaptureRef :: argCaptureRefs = formalCaptures.map(_.ref) + val thisCaptureRef :: argCaptureRefs = formalCaptures.map(_.ref): @unchecked if (!sym.owner.isNonNativeJSClass || sym.isJSExposed) genApplyMethodMaybeStatically(thisCaptureRef, sym, argCaptureRefs ::: actualParams) else @@ -3458,7 +3458,7 @@ class JSCodeGen()(using genCtx: Context) { } if (isThisFunction) { - val thisParam :: otherParams = formalParams + val thisParam :: otherParams = formalParams: @unchecked js.Closure( arrow = false, formalCaptures, @@ -3970,7 +3970,7 @@ class JSCodeGen()(using genCtx: Context) { */ private def genReflectiveCall(tree: Apply, isSelectDynamic: Boolean): js.Tree = { implicit val pos = tree.span - val Apply(fun @ Select(receiver, _), args) = tree + val Apply(fun @ Select(receiver, _), args) = tree: @unchecked val selectedValueTree = js.Apply(js.ApplyFlags.empty, genExpr(receiver), js.MethodIdent(selectedValueMethodName), Nil)(jstpe.AnyType) @@ -4213,7 +4213,7 @@ class JSCodeGen()(using genCtx: Context) { private def genCaptureValuesFromFakeNewInstance(tree: Tree): List[js.Tree] = { implicit val pos: Position = tree.span - val Apply(fun @ Select(New(_), _), args) = tree + val Apply(fun @ Select(New(_), _), args) = tree: @unchecked val sym = fun.symbol /* We use the same strategy as genActualJSArgs to detect which parameters were @@ -4539,7 +4539,7 @@ class JSCodeGen()(using genCtx: Context) { pathName.split('.').toList def parseGlobalPath(pathName: String): Global = { - val globalRef :: path = parsePath(pathName) + val globalRef :: path = parsePath(pathName): @unchecked Global(globalRef, path) } diff --git a/compiler/src/dotty/tools/backend/sjs/JSExportsGen.scala b/compiler/src/dotty/tools/backend/sjs/JSExportsGen.scala index c9dbdaf68812..a163915d8d75 100644 --- a/compiler/src/dotty/tools/backend/sjs/JSExportsGen.scala +++ b/compiler/src/dotty/tools/backend/sjs/JSExportsGen.scala @@ -356,7 +356,7 @@ final class JSExportsGen(jsCodeGen: JSCodeGen)(using Context) { None } else { val formalArgsRegistry = new FormalArgsRegistry(1, false) - val (List(arg), None) = formalArgsRegistry.genFormalArgs() + val (List(arg), None) = formalArgsRegistry.genFormalArgs(): @unchecked val body = genOverloadDispatchSameArgc(jsName, formalArgsRegistry, setters.map(new ExportedSymbol(_, static)), jstpe.AnyType, None) Some((arg, body)) diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index c49246858f5c..faf420fcc44c 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -405,7 +405,7 @@ object desugar { /** The expansion of a class definition. See inline comments for what is involved */ def classDef(cdef: TypeDef)(using Context): Tree = { - val impl @ Template(constr0, _, self, _) = cdef.rhs + val impl @ Template(constr0, _, self, _) = cdef.rhs: @unchecked val className = normalizeName(cdef, impl).asTypeName val parents = impl.parents val mods = cdef.mods @@ -695,7 +695,7 @@ object desugar { .withMods(companionMods | Synthetic)) .withSpan(cdef.span).toList if (companionDerived.nonEmpty) - for (modClsDef @ TypeDef(_, _) <- mdefs) + for (case modClsDef @ TypeDef(_, _) <- mdefs) modClsDef.putAttachment(DerivingCompanion, impl.srcPos.startPos) mdefs } @@ -753,7 +753,7 @@ object desugar { enumCompanionRef match { case ref: TermRefTree => // have the enum import watch the companion object - val (modVal: ValDef) :: _ = companions + val (modVal: ValDef) :: _ = companions: @unchecked ref.watching(modVal) case _ => } @@ -1215,7 +1215,7 @@ object desugar { /** Expand variable identifier x to x @ _ */ def patternVar(tree: Tree)(using Context): Bind = { - val Ident(name) = unsplice(tree) + val Ident(name) = unsplice(tree): @unchecked Bind(name, Ident(nme.WILDCARD)).withSpan(tree.span) } diff --git a/compiler/src/dotty/tools/dotc/ast/MainProxies.scala b/compiler/src/dotty/tools/dotc/ast/MainProxies.scala index 1133d015f69f..040582476e96 100644 --- a/compiler/src/dotty/tools/dotc/ast/MainProxies.scala +++ b/compiler/src/dotty/tools/dotc/ast/MainProxies.scala @@ -183,7 +183,7 @@ object MainProxies { case TypeDef(_, template: Template) => template.body.flatMap((_: Tree) match { case dd: DefDef if dd.name.is(DefaultGetterName) && dd.name.firstPart == funSymbol.name => - val DefaultGetterName.NumberedInfo(index) = dd.name.info + val DefaultGetterName.NumberedInfo(index) = dd.name.info: @unchecked List(index -> dd.symbol) case _ => Nil }).toMap diff --git a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala index 2c65dac8ec61..3ca0d3bcfa67 100644 --- a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala +++ b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala @@ -956,7 +956,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] => Some(tree.args.head) else if tree.symbol == defn.QuotedTypeModule_of then // quoted.Type.of[](quotes) - val TypeApply(_, body :: _) = tree.fun + val TypeApply(_, body :: _) = tree.fun: @unchecked Some(body) else None } diff --git a/compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala b/compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala index 2ccd646c3226..87974218fb0f 100644 --- a/compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala +++ b/compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala @@ -156,9 +156,10 @@ class TreeTypeMap( private def transformAllParamss(paramss: List[ParamClause]): (TreeTypeMap, List[ParamClause]) = paramss match case params :: paramss1 => - val (tmap1, params1: ParamClause) = (params: @unchecked) match + val (tmap1, params1: ParamClause) = ((params: @unchecked) match case ValDefs(vparams) => transformDefs(vparams) case TypeDefs(tparams) => transformDefs(tparams) + ): @unchecked val (tmap2, paramss2) = tmap1.transformAllParamss(paramss1) (tmap2, params1 :: paramss2) case nil => diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala index 2e87194ff207..d4cf61f35829 100644 --- a/compiler/src/dotty/tools/dotc/ast/tpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala @@ -293,7 +293,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { ta.assignType(untpd.TypeDef(sym.name, TypeTree(sym.info)), sym) def ClassDef(cls: ClassSymbol, constr: DefDef, body: List[Tree], superArgs: List[Tree] = Nil)(using Context): TypeDef = { - val firstParent :: otherParents = cls.info.parents + val firstParent :: otherParents = cls.info.parents: @unchecked val superRef = if (cls.is(Trait)) TypeTree(firstParent) else { diff --git a/compiler/src/dotty/tools/dotc/config/Settings.scala b/compiler/src/dotty/tools/dotc/config/Settings.scala index 3cd7b88b5471..277833afbd5d 100644 --- a/compiler/src/dotty/tools/dotc/config/Settings.scala +++ b/compiler/src/dotty/tools/dotc/config/Settings.scala @@ -84,7 +84,7 @@ object Settings: } def tryToSet(state: ArgsSummary): ArgsSummary = { - val ArgsSummary(sstate, arg :: args, errors, warnings) = state + val ArgsSummary(sstate, arg :: args, errors, warnings) = state: @unchecked def update(value: Any, args: List[String]): ArgsSummary = var dangers = warnings val value1 = diff --git a/compiler/src/dotty/tools/dotc/core/Annotations.scala b/compiler/src/dotty/tools/dotc/core/Annotations.scala index c44d7ebe8e7b..8eca364e4621 100644 --- a/compiler/src/dotty/tools/dotc/core/Annotations.scala +++ b/compiler/src/dotty/tools/dotc/core/Annotations.scala @@ -34,10 +34,10 @@ object Annotations { if (i < args.length) Some(args(i)) else None } def argumentConstant(i: Int)(using Context): Option[Constant] = - for (ConstantType(c) <- argument(i) map (_.tpe.widenTermRefExpr.normalized)) yield c + for (case ConstantType(c) <- argument(i) map (_.tpe.widenTermRefExpr.normalized)) yield c def argumentConstantString(i: Int)(using Context): Option[String] = - for (Constant(s: String) <- argumentConstant(i)) yield s + for (case Constant(s: String) <- argumentConstant(i)) yield s /** The tree evaluaton is in progress. */ def isEvaluating: Boolean = false @@ -219,7 +219,7 @@ object Annotations { def unapply(ann: Annotation)(using Context): Option[Symbol] = if (ann.symbol == defn.ChildAnnot) { - val AppliedType(_, (arg: NamedType) :: Nil) = ann.tree.tpe + val AppliedType(_, (arg: NamedType) :: Nil) = ann.tree.tpe: @unchecked Some(arg.symbol) } else None diff --git a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala index f786dbc833f9..0fdaec68e826 100644 --- a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala +++ b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala @@ -269,7 +269,7 @@ trait ConstraintHandling { (c1 eq constraint) || { constraint = c1 - val TypeBounds(lo, hi) = constraint.entry(param) + val TypeBounds(lo, hi) = constraint.entry(param): @unchecked isSub(lo, hi) } end addOneBound @@ -368,7 +368,7 @@ trait ConstraintHandling { if level1 != level2 then boundRemoved = LevelAvoidMap(-1, math.min(level1, level2))(boundRemoved) - val TypeBounds(lo, hi) = boundRemoved + val TypeBounds(lo, hi) = boundRemoved: @unchecked // After avoidance, the interval might be empty, e.g. in // tests/pos/i8900-promote.scala: // >: x.type <: Singleton @@ -416,7 +416,7 @@ trait ConstraintHandling { */ protected final def isSatisfiable(using Context): Boolean = constraint.forallParams { param => - val TypeBounds(lo, hi) = constraint.entry(param) + val TypeBounds(lo, hi) = constraint.entry(param): @unchecked isSub(lo, hi) || { report.log(i"sub fail $lo <:< $hi") false diff --git a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala index 675816ad200f..fa41b5adf9f2 100644 --- a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala +++ b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala @@ -518,7 +518,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds, if (tl.isInstanceOf[HKLambda]) { // HKLambdas are hash-consed, need to create an artificial difference by adding // a LazyRef to a bound. - val TypeBounds(lo, hi) :: pinfos1 = tl.paramInfos + val TypeBounds(lo, hi) :: pinfos1 = tl.paramInfos: @unchecked paramInfos = TypeBounds(lo, LazyRef.of(hi)) :: pinfos1 } ensureFresh(tl.newLikeThis(tl.paramNames, paramInfos, tl.resultType)) diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index b3aaca843c10..bb30dbf7b7e9 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -2150,8 +2150,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling def lubArgs(args1: List[Type], args2: List[Type], tparams: List[TypeParamInfo], canConstrain: Boolean = false): List[Type] = tparams match { case tparam :: tparamsRest => - val arg1 :: args1Rest = args1 - val arg2 :: args2Rest = args2 + val arg1 :: args1Rest = args1: @unchecked + val arg2 :: args2Rest = args2: @unchecked val common = singletonInterval(arg1, arg2) val v = tparam.paramVarianceSign val lubArg = @@ -2182,8 +2182,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling def glbArgs(args1: List[Type], args2: List[Type], tparams: List[TypeParamInfo]): List[Type] = tparams match { case tparam :: tparamsRest => - val arg1 :: args1Rest = args1 - val arg2 :: args2Rest = args2 + val arg1 :: args1Rest = args1: @unchecked + val arg2 :: args2Rest = args2: @unchecked val common = singletonInterval(arg1, arg2) val v = tparam.paramVarianceSign val glbArg = @@ -2921,7 +2921,7 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) { cas } - val defn.MatchCase(pat, body) = cas1 + val defn.MatchCase(pat, body) = cas1: @unchecked if (isSubType(scrut, pat)) // `scrut` is a subtype of `pat`: *It's a Match!* diff --git a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala index 29b40670e8e3..2caa639592b3 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala @@ -680,7 +680,7 @@ class TypeErasure(sourceLanguage: SourceLanguage, semiEraseVCs: Boolean, isConst } private def eraseArray(tp: Type)(using Context) = { - val defn.ArrayOf(elemtp) = tp + val defn.ArrayOf(elemtp) = tp: @unchecked if (isGenericArrayElement(elemtp, isScala2 = sourceLanguage.isScala2)) defn.ObjectType else try JavaArrayType(erasureFn(sourceLanguage, semiEraseVCs = false, isConstructor, isSymbol, wildcardOK)(elemtp)) diff --git a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala index a45ff756173a..56c0f8ac6e42 100644 --- a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala +++ b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala @@ -283,7 +283,7 @@ class ClassfileParser( */ def normalizeConstructorParams() = innerClasses.get(currentClassName.toString) match { case Some(entry) if !isStatic(entry.jflags) => - val mt @ MethodTpe(paramNames, paramTypes, resultType) = denot.info + val mt @ MethodTpe(paramNames, paramTypes, resultType) = denot.info: @unchecked var normalizedParamNames = paramNames.tail var normalizedParamTypes = paramTypes.tail if ((jflags & JAVA_ACC_SYNTHETIC) != 0) { diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyPickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyPickler.scala index 1ff1642ecce1..1435ead8fbb4 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TastyPickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyPickler.scala @@ -41,7 +41,7 @@ class TastyPickler(val rootCls: ClassSymbol) { sections.foreach(_._2.assemble()) val nameBufferHash = TastyHash.pjwHash64(nameBuffer.bytes) - val treeSectionHash +: otherSectionHashes = sections.map(x => TastyHash.pjwHash64(x._2.bytes)) + val treeSectionHash +: otherSectionHashes = sections.map(x => TastyHash.pjwHash64(x._2.bytes)): @unchecked val tastyVersion = ctx.tastyVersion diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala index 09aae581fcfc..7c77a087fe50 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala @@ -375,7 +375,7 @@ class TreePickler(pickler: TastyPickler) { if (qual.isEmpty) pickleType(tree.tpe) else { writeByte(QUALTHIS) - val ThisType(tref) = tree.tpe + val ThisType(tref) = tree.tpe: @unchecked pickleTree(qual.withType(tref)) } case Select(qual, name) => @@ -385,7 +385,7 @@ class TreePickler(pickler: TastyPickler) { withLength { writeNat(levels) pickleTree(qual) - val SkolemType(tp) = tree.tpe + val SkolemType(tp) = tree.tpe: @unchecked pickleType(tp) } case _ => @@ -439,7 +439,7 @@ class TreePickler(pickler: TastyPickler) { withLength { pickleTree(qual); if (!mix.isEmpty) { - val SuperType(_, mixinType: TypeRef) = tree.tpe + val SuperType(_, mixinType: TypeRef) = tree.tpe: @unchecked pickleTree(mix.withType(mixinType)) } } @@ -560,7 +560,7 @@ class TreePickler(pickler: TastyPickler) { withLength { pickleParams(params) tree.parents.foreach(pickleTree) - val cinfo @ ClassInfo(_, _, _, _, selfInfo) = tree.symbol.owner.info + val cinfo @ ClassInfo(_, _, _, _, selfInfo) = tree.symbol.owner.info: @unchecked if (!tree.self.isEmpty) { writeByte(SELFDEF) pickleName(tree.self.name) diff --git a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala index dbd3e15dcc2d..2bb3455dfde7 100644 --- a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala @@ -81,7 +81,7 @@ object Scala2Unpickler { val (tparams, TempClassInfoType(parents, decls, clazz)) = info match { case TempPolyType(tps, cinfo) => (tps, cinfo) case cinfo => (Nil, cinfo) - } + }: @unchecked val ost = if (selfInfo eq NoType) && denot.is(ModuleClass) then val sourceModule = denot.sourceModule.orElse { @@ -1101,7 +1101,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas val tparams = until(end, () => readTypeDefRef()) val cls = symbol.asClass val ((constr: DefDef) :: Nil, stats) = - impl.body.partition(_.symbol == cls.primaryConstructor) + impl.body.partition(_.symbol == cls.primaryConstructor): @unchecked ClassDef(cls, constr, tparams ++ stats) case MODULEtree => diff --git a/compiler/src/dotty/tools/dotc/interactive/Interactive.scala b/compiler/src/dotty/tools/dotc/interactive/Interactive.scala index 8ec7d52c98f6..2cc2e1f5e926 100644 --- a/compiler/src/dotty/tools/dotc/interactive/Interactive.scala +++ b/compiler/src/dotty/tools/dotc/interactive/Interactive.scala @@ -108,7 +108,7 @@ object Interactive { val classTree = funSym.topLevelClass.asClass.rootTree val paramSymbol = for { - DefDef(_, paramss, _, _) <- tpd.defPath(funSym, classTree).lastOption + case DefDef(_, paramss, _, _) <- tpd.defPath(funSym, classTree).lastOption param <- paramss.flatten.find(_.name == name) } yield param.symbol diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index e42da990c742..c78e4cd8fb2f 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -1386,7 +1386,7 @@ object Parsers { syntaxError("context function types require at least one parameter", paramSpan) new FunctionWithMods(params, t, imods) else if !ctx.settings.YkindProjector.isDefault then - val (newParams :+ newT, tparams) = replaceKindProjectorPlaceholders(params :+ t) + val (newParams :+ newT, tparams) = replaceKindProjectorPlaceholders(params :+ t): @unchecked lambdaAbstract(tparams, Function(newParams, newT)) else @@ -2100,7 +2100,7 @@ object Parsers { case _ => val tpt = typeDependingOn(location) if (isWildcard(t) && !location.inPattern) { - val vd :: rest = placeholderParams + val vd :: rest = placeholderParams: @unchecked placeholderParams = cpy.ValDef(vd)(tpt = tpt).withSpan(vd.span.union(tpt.span)) :: rest } diff --git a/compiler/src/dotty/tools/dotc/plugins/Plugins.scala b/compiler/src/dotty/tools/dotc/plugins/Plugins.scala index 85acc22ecdef..bcc0c221f78b 100644 --- a/compiler/src/dotty/tools/dotc/plugins/Plugins.scala +++ b/compiler/src/dotty/tools/dotc/plugins/Plugins.scala @@ -62,7 +62,7 @@ trait Plugins { plugNames: Set[String]): List[Plugin] = { if (plugins.isEmpty) return Nil // early return - val plug :: tail = plugins + val plug :: tail = plugins: @unchecked def withoutPlug = pick(tail, plugNames) def withPlug = plug :: pick(tail, plugNames + plug.name) diff --git a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala index 1d516cdd40a4..94c57e025067 100644 --- a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala @@ -170,7 +170,7 @@ class PlainPrinter(_ctx: Context) extends Printer { (toTextLocal(tycon) ~ "[" ~ argsText(args) ~ "]").close case tp: RefinedType => val parent :: (refined: List[RefinedType @unchecked]) = - refinementChain(tp).reverse + refinementChain(tp).reverse: @unchecked toTextLocal(parent) ~ "{" ~ Text(refined map toTextRefinement, "; ").close ~ "}" case tp: RecType => try { diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala index 9401efc58135..8bdf1d4822ce 100644 --- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -220,7 +220,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { else if defn.isFunctionClass(cls) then toTextFunction(args, cls.name.isContextFunction, cls.name.isErasedFunction) else if tp.tupleArity >= 2 && !printDebug then toTextTuple(tp.tupleElementTypes) else if isInfixType(tp) then - val l :: r :: Nil = args + val l :: r :: Nil = args: @unchecked val opName = tyconName(tycon) toTextInfixType(tyconName(tycon), l, r) { simpleNameString(tycon.typeSymbol) } else Str("") diff --git a/compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala index 2e0454c3a7aa..d44ef4e52d4c 100644 --- a/compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala @@ -81,7 +81,7 @@ object PickledQuotes { /** Unpickle the tree contained in the TastyExpr */ def unpickleTerm(pickled: String | List[String], typeHole: TypeHole, termHole: ExprHole)(using Context): Tree = { val unpickled = withMode(Mode.ReadPositions)(unpickle(pickled, isType = false)) - val Inlined(call, Nil, expansion) = unpickled + val Inlined(call, Nil, expansion) = unpickled: @unchecked val inlineCtx = inlineContext(call) val expansion1 = spliceTypes(expansion, typeHole)(using inlineCtx) val expansion2 = spliceTerms(expansion1, typeHole, termHole)(using inlineCtx) @@ -120,7 +120,7 @@ object PickledQuotes { // // Replaces type holes generated by PickleQuotes (non-spliced types). // These are types defined in a quote and used at the same level in a nested quote. - val TypeHole.V1(evalHole) = typeHole + val TypeHole.V1(evalHole) = typeHole: @unchecked val quotedType = evalHole.nn.apply(idx, reifyTypeHoleArgs(args)) PickledQuotes.quotedTypeToTree(quotedType) } @@ -172,7 +172,7 @@ object PickledQuotes { // To keep for backwards compatibility. In some older version we missed the creation of some holes. tpt case TypeHole.V2(types) => - val Hole(_, idx, _, _, _) = tdef.rhs + val Hole(_, idx, _, _, _) = tdef.rhs: @unchecked PickledQuotes.quotedTypeToTree(types.nn.apply(idx)) (tdef.symbol, tree.tpe) }.toMap diff --git a/compiler/src/dotty/tools/dotc/reporting/messages.scala b/compiler/src/dotty/tools/dotc/reporting/messages.scala index 48135f9aa35d..f822f9a62108 100644 --- a/compiler/src/dotty/tools/dotc/reporting/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/messages.scala @@ -424,7 +424,7 @@ import transform.SymUtils._ def msg = em"""An ${hl("implicit class")} may not be top-level""" def explain = { - val TypeDef(name, impl @ Template(constr0, parents, self, _)) = cdef + val TypeDef(name, impl @ Template(constr0, parents, self, _)) = cdef: @unchecked val exampleArgs = if(constr0.termParamss.isEmpty) "..." else constr0.termParamss(0).map(_.withMods(untpd.Modifiers()).show).mkString(", ") diff --git a/compiler/src/dotty/tools/dotc/semanticdb/Scala3.scala b/compiler/src/dotty/tools/dotc/semanticdb/Scala3.scala index 979fc4f6acb4..9738eea43960 100644 --- a/compiler/src/dotty/tools/dotc/semanticdb/Scala3.scala +++ b/compiler/src/dotty/tools/dotc/semanticdb/Scala3.scala @@ -184,8 +184,8 @@ object Scala3: val EmptyPackage: String = "_empty_/" val LocalPrefix: String = "local" val PackageObjectDescriptor: String = "package." - val s"${RootPackageName @ _}/" = RootPackage - val s"${EmptyPackageName @ _}/" = EmptyPackage + val s"${RootPackageName @ _}/" = RootPackage: @unchecked + val s"${EmptyPackageName @ _}/" = EmptyPackage: @unchecked def displaySymbol(symbol: Symbol)(using Context): String = if symbol.isPackageObject then diff --git a/compiler/src/dotty/tools/dotc/transform/ArrayConstructors.scala b/compiler/src/dotty/tools/dotc/transform/ArrayConstructors.scala index 2b02e94e4f0f..e783961649dd 100644 --- a/compiler/src/dotty/tools/dotc/transform/ArrayConstructors.scala +++ b/compiler/src/dotty/tools/dotc/transform/ArrayConstructors.scala @@ -30,11 +30,11 @@ class ArrayConstructors extends MiniPhase { tpd.newArray(elemType, tree.tpe, tree.span, JavaSeqLiteral(dims, TypeTree(defn.IntClass.typeRef))) if (tree.fun.symbol eq defn.ArrayConstructor) { - val TypeApply(tycon, targ :: Nil) = tree.fun + val TypeApply(tycon, targ :: Nil) = tree.fun: @unchecked expand(targ.tpe, tree.args) } else if ((tree.fun.symbol.maybeOwner eq defn.ArrayModuleClass) && (tree.fun.symbol.name eq nme.ofDim) && !tree.tpe.isInstanceOf[MethodicType]) { - val Apply(Apply(TypeApply(_, List(tp)), _), _) = tree + val Apply(Apply(TypeApply(_, List(tp)), _), _) = tree: @unchecked val cs = tp.tpe.classSymbol tree.fun match { case Apply(TypeApply(t: Ident, targ), dims) diff --git a/compiler/src/dotty/tools/dotc/transform/Constructors.scala b/compiler/src/dotty/tools/dotc/transform/Constructors.scala index a897165ac671..d8cc76973233 100644 --- a/compiler/src/dotty/tools/dotc/transform/Constructors.scala +++ b/compiler/src/dotty/tools/dotc/transform/Constructors.scala @@ -130,7 +130,7 @@ class Constructors extends MiniPhase with IdentityDenotTransformer { thisPhase = override def transformTemplate(tree: Template)(using Context): Tree = { val cls = ctx.owner.asClass - val constr @ DefDef(nme.CONSTRUCTOR, (vparams: List[ValDef] @unchecked) :: Nil, _, EmptyTree) = tree.constr + val constr @ DefDef(nme.CONSTRUCTOR, (vparams: List[ValDef] @unchecked) :: Nil, _, EmptyTree) = tree.constr: @unchecked // Produce aligned accessors and constructor parameters. We have to adjust // for any outer parameters, which are last in the sequence of original diff --git a/compiler/src/dotty/tools/dotc/transform/ElimByName.scala b/compiler/src/dotty/tools/dotc/transform/ElimByName.scala index 3a91f6623243..efdd18291821 100644 --- a/compiler/src/dotty/tools/dotc/transform/ElimByName.scala +++ b/compiler/src/dotty/tools/dotc/transform/ElimByName.scala @@ -146,7 +146,7 @@ class ElimByName extends MiniPhase, InfoTransformer: case _ => arg - val mt @ MethodType(_) = tree.fun.tpe.widen + val mt @ MethodType(_) = tree.fun.tpe.widen: @unchecked val args1 = tree.args.zipWithConserve(mt.paramInfos)(transformArg) cpy.Apply(tree)(tree.fun, args1) } diff --git a/compiler/src/dotty/tools/dotc/transform/ElimOuterSelect.scala b/compiler/src/dotty/tools/dotc/transform/ElimOuterSelect.scala index f161cd4f8cb7..3ddc8b614bae 100644 --- a/compiler/src/dotty/tools/dotc/transform/ElimOuterSelect.scala +++ b/compiler/src/dotty/tools/dotc/transform/ElimOuterSelect.scala @@ -27,7 +27,7 @@ class ElimOuterSelect extends MiniPhase { override def transformSelect(tree: Select)(using Context): Tree = tree.name match { case OuterSelectName(_, nhops) => - val SkolemType(tp) = tree.tpe + val SkolemType(tp) = tree.tpe: @unchecked ExplicitOuter.outer.path(start = tree.qualifier, count = nhops).ensureConforms(tp) case _ => tree } diff --git a/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala b/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala index b91da4e9de88..9e4e45829cff 100644 --- a/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala +++ b/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala @@ -179,7 +179,7 @@ class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase => .symbol.asTerm // Generate the method val forwarderDef = DefDef(forwarderSym, prefss => { - val init :+ (last :+ vararg) = prefss + val init :+ (last :+ vararg) = prefss: @unchecked // Can't call `.argTypes` here because the underlying array type is of the // form `Array[? <: SomeType]`, so we need `.argInfos` to get the `TypeBounds`. val elemtp = vararg.tpe.widen.argInfos.head @@ -200,7 +200,7 @@ class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase => */ private def isValidJavaVarArgs(tp: Type)(using Context): Boolean = tp match case mt: MethodType => - val initp :+ lastp = mt.paramInfoss + val initp :+ lastp = mt.paramInfoss: @unchecked initp.forall(_.forall(!_.isRepeatedParam)) && lastp.nonEmpty && lastp.init.forall(!_.isRepeatedParam) && @@ -272,7 +272,7 @@ class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase => case m: MethodType => // multiple param lists tp.derivedLambdaType(tp.paramNames, tp.paramInfos, toJavaVarArgs(m)) case _ => - val init :+ last = tp.paramInfos + val init :+ last = tp.paramInfos: @unchecked val vararg = varargArrayType(last) tp.derivedLambdaType(tp.paramNames, init :+ vararg, tp.resultType) diff --git a/compiler/src/dotty/tools/dotc/transform/Erasure.scala b/compiler/src/dotty/tools/dotc/transform/Erasure.scala index 123f2a7aaeb8..223eef5c39bf 100644 --- a/compiler/src/dotty/tools/dotc/transform/Erasure.scala +++ b/compiler/src/dotty/tools/dotc/transform/Erasure.scala @@ -73,7 +73,7 @@ class Erasure extends Phase with DenotTransformer { assert(ctx.phase == this, s"transforming $ref at ${ctx.phase}") if (ref.symbol eq defn.ObjectClass) { // After erasure, all former Any members are now Object members - val ClassInfo(pre, _, ps, decls, selfInfo) = ref.info + val ClassInfo(pre, _, ps, decls, selfInfo) = ref.info: @unchecked val extendedScope = decls.cloneScope for decl <- defn.AnyClass.classInfo.decls do if !decl.isConstructor then extendedScope.enter(decl) @@ -452,7 +452,7 @@ object Erasure { val implReturnsUnit = implResultType.classSymbol eq defn.UnitClass // The SAM that this closure should implement. // At this point it should be already guaranteed that there's only one method to implement - val Seq(sam: MethodType) = lambdaType.possibleSamMethods.map(_.info) + val Seq(sam: MethodType) = lambdaType.possibleSamMethods.map(_.info): @unchecked val samParamTypes = sam.paramInfos val samResultType = sam.resultType @@ -713,7 +713,7 @@ object Erasure { def adaptIfSuper(qual: Tree): Tree = qual match { case Super(thisQual, untpd.EmptyTypeIdent) => - val SuperType(thisType, supType) = qual.tpe + val SuperType(thisType, supType) = qual.tpe: @unchecked if (sym.owner.is(Flags.Trait)) cpy.Super(qual)(thisQual, untpd.Ident(sym.owner.asClass.name)) .withType(SuperType(thisType, sym.owner.typeRef)) diff --git a/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala b/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala index 6f2aa7d970ac..8dba16951c6f 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala @@ -106,7 +106,7 @@ class ExpandSAMs extends MiniPhase: * ``` */ private def toPartialFunction(tree: Block, tpe: Type)(using Context): Tree = { - val closureDef(anon @ DefDef(_, List(List(param)), _, _)) = tree + val closureDef(anon @ DefDef(_, List(List(param)), _, _)) = tree: @unchecked // The right hand side from which to construct the partial function. This is always a Match. // If the original rhs is already a Match (possibly in braces), return that. diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala index 0a9798226d76..978ec2ce777f 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala @@ -370,7 +370,7 @@ object ExplicitOuter { /** If `cls` has an outer parameter add one to the method type `tp`. */ def addParam(cls: ClassSymbol, tp: Type): Type = if (needsOuterParam(cls)) { - val mt @ MethodTpe(pnames, ptypes, restpe) = tp + val mt @ MethodTpe(pnames, ptypes, restpe) = tp: @unchecked mt.derivedLambdaType( nme.OUTER :: pnames, outerClass(cls).typeRef :: ptypes, restpe) } diff --git a/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala b/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala index 3869818fb129..8ca600577244 100644 --- a/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala +++ b/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala @@ -152,7 +152,7 @@ trait FullParameterization { val origClass = origMeth.enclosingClass.asClass val origLeadingTypeParamSyms = allInstanceTypeParams(originalDef, abstractOverClass) val origOtherParamSyms = originalDef.trailingParamss.flatten.map(_.symbol) - val thisRef :: argRefs = vrefss.flatten + val thisRef :: argRefs = vrefss.flatten: @unchecked /** If tree should be rewired, the rewired tree, otherwise EmptyTree. * @param targs Any type arguments passed to the rewired tree. diff --git a/compiler/src/dotty/tools/dotc/transform/FunctionXXLForwarders.scala b/compiler/src/dotty/tools/dotc/transform/FunctionXXLForwarders.scala index a7fa5c0fe909..cc1c0048b68f 100644 --- a/compiler/src/dotty/tools/dotc/transform/FunctionXXLForwarders.scala +++ b/compiler/src/dotty/tools/dotc/transform/FunctionXXLForwarders.scala @@ -45,7 +45,7 @@ class FunctionXXLForwarders extends MiniPhase with IdentityDenotTransformer { val forwarders = for { - (ddef: DefDef) <- impl.body + case (ddef: DefDef) <- impl.body if ddef.name == nme.apply && ddef.symbol.is(Method) && ddef.symbol.signature.paramsSig.size > MaxImplementedFunctionArity && ddef.symbol.allOverriddenSymbols.exists(sym => defn.isXXLFunctionClass(sym.owner)) diff --git a/compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala b/compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala index 6ce708068393..a8542a6e4394 100644 --- a/compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala +++ b/compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala @@ -76,7 +76,7 @@ object GenericSignatures { * of `AndType` in `jsig` which already supports `def foo(x: A & Object)`. */ def boundsSig(bounds: List[Type]): Unit = { - val (repr :: _, others) = splitIntersection(bounds) + val (repr :: _, others) = splitIntersection(bounds): @unchecked builder.append(':') // In Java, intersections always erase to their first member, so put diff --git a/compiler/src/dotty/tools/dotc/transform/Memoize.scala b/compiler/src/dotty/tools/dotc/transform/Memoize.scala index 0bbe0dc775a0..d20f3e1a8da4 100644 --- a/compiler/src/dotty/tools/dotc/transform/Memoize.scala +++ b/compiler/src/dotty/tools/dotc/transform/Memoize.scala @@ -167,7 +167,7 @@ class Memoize extends MiniPhase with IdentityDenotTransformer { thisPhase => removeUnwantedAnnotations(sym, defn.GetterMetaAnnot) Thicket(fieldDef, getterDef) else if sym.isSetter then - if (!sym.is(ParamAccessor)) { val Literal(Constant(())) = tree.rhs } // This is intended as an assertion + if (!sym.is(ParamAccessor)) { val Literal(Constant(())) = tree.rhs: @unchecked } // This is intended as an assertion val field = sym.field if !field.exists then // When transforming the getter, we determined that no field was needed. diff --git a/compiler/src/dotty/tools/dotc/transform/Mixin.scala b/compiler/src/dotty/tools/dotc/transform/Mixin.scala index 4ab6a5c9a646..b6aeb7c21511 100644 --- a/compiler/src/dotty/tools/dotc/transform/Mixin.scala +++ b/compiler/src/dotty/tools/dotc/transform/Mixin.scala @@ -218,7 +218,7 @@ class Mixin extends MiniPhase with SymTransformer { thisPhase => } (scall, stats ::: inits, args) case _ => - val Apply(sel @ Select(New(_), nme.CONSTRUCTOR), args) = tree + val Apply(sel @ Select(New(_), nme.CONSTRUCTOR), args) = tree: @unchecked val (callArgs, initArgs) = if (tree.symbol.owner.is(Trait)) (Nil, args) else (args, Nil) (superRef(tree.symbol, tree.span).appliedToTermArgs(callArgs), Nil, initArgs) } diff --git a/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala b/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala index 012cec761aff..263b0040eb24 100644 --- a/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala +++ b/compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala @@ -114,7 +114,7 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages( if body.isTerm then // `quoted.runtime.Expr.quote[T]()` --> `quoted.runtime.Expr.quote[T2]()` - val TypeApply(fun, targs) = quote.fun + val TypeApply(fun, targs) = quote.fun: @unchecked val targs2 = targs.map(targ => TypeTree(healTypeOfTerm(quote.fun.srcPos)(targ.tpe))) cpy.Apply(quote)(cpy.TypeApply(quote.fun)(fun, targs2), body2 :: Nil) else @@ -125,7 +125,7 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages( ref(x) case _ => // `quoted.Type.of[](quotes)` --> `quoted.Type.of[](quotes)` - val TypeApply(fun, _) = quote.fun + val TypeApply(fun, _) = quote.fun: @unchecked cpy.Apply(quote)(cpy.TypeApply(quote.fun)(fun, body2 :: Nil), quotes) } diff --git a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala index 14e2b674446c..981338697e4c 100644 --- a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala +++ b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala @@ -261,7 +261,7 @@ object PatternMatcher { def matchArgsPatternPlan(args: List[Tree], syms: List[Symbol]): Plan = args match { case arg :: args1 => - val sym :: syms1 = syms + val sym :: syms1 = syms: @unchecked patternPlan(sym, arg, matchArgsPatternPlan(args1, syms1)) case Nil => assert(syms.isEmpty) @@ -411,7 +411,7 @@ object PatternMatcher { assert(implicits.isEmpty) acc } - val mt @ MethodType(_) = extractor.tpe.widen + val mt @ MethodType(_) = extractor.tpe.widen: @unchecked val unapp0 = extractor.appliedTo(ref(scrutinee).ensureConforms(mt.paramInfos.head)) val unapp = applyImplicits(unapp0, implicits, mt.resultType) unapplyPlan(unapp, args) @@ -659,7 +659,7 @@ object PatternMatcher { */ private def inlineVars(plan: Plan): Plan = { val refCount = varRefCount(plan) - val LetPlan(topSym, _) = plan + val LetPlan(topSym, _) = plan: @unchecked def toDrop(sym: Symbol) = initializer.get(sym) match { case Some(rhs) => @@ -864,7 +864,7 @@ object PatternMatcher { else (scrutinee.select(nme.toInt), defn.IntType) def primLiteral(lit: Tree): Tree = - val Literal(constant) = lit + val Literal(constant) = lit: @unchecked if (constant.tag == Constants.IntTag) lit else if (constant.tag == Constants.StringTag) lit else cpy.Literal(lit)(Constant(constant.intValue)) diff --git a/compiler/src/dotty/tools/dotc/transform/PickleQuotes.scala b/compiler/src/dotty/tools/dotc/transform/PickleQuotes.scala index a12ef6d50bed..1cd5edf85052 100644 --- a/compiler/src/dotty/tools/dotc/transform/PickleQuotes.scala +++ b/compiler/src/dotty/tools/dotc/transform/PickleQuotes.scala @@ -317,12 +317,12 @@ object PickleQuotes { defn.QuotedExprClass.typeRef.appliedTo(defn.AnyType)), args => val cases = termSplices.map { case (splice, idx) => - val defn.FunctionOf(argTypes, defn.FunctionOf(quotesType :: _, _, _, _), _, _) = splice.tpe + val defn.FunctionOf(argTypes, defn.FunctionOf(quotesType :: _, _, _, _), _, _) = splice.tpe: @unchecked val rhs = { val spliceArgs = argTypes.zipWithIndex.map { (argType, i) => args(1).select(nme.apply).appliedTo(Literal(Constant(i))).asInstance(argType) } - val Block(List(ddef: DefDef), _) = splice + val Block(List(ddef: DefDef), _) = splice: @unchecked // TODO: beta reduce inner closure? Or wait until BetaReduce phase? BetaReduce(ddef, spliceArgs).select(nme.apply).appliedTo(args(2).asInstance(quotesType)) } diff --git a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala index 1b3ff3f0dd7e..86d63c72ac47 100644 --- a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala +++ b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala @@ -225,7 +225,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase case (NamedArg(_, arg) :: _, namedArgs1) => arg :: reorderArgs(pnames1, namedArgs1, otherArgs) case _ => - val otherArg :: otherArgs1 = otherArgs + val otherArg :: otherArgs1 = otherArgs: @unchecked otherArg :: reorderArgs(pnames1, namedArgs, otherArgs1) } case nil => diff --git a/compiler/src/dotty/tools/dotc/transform/Splicer.scala b/compiler/src/dotty/tools/dotc/transform/Splicer.scala index 3a2c1792dfa4..31c28d7b1854 100644 --- a/compiler/src/dotty/tools/dotc/transform/Splicer.scala +++ b/compiler/src/dotty/tools/dotc/transform/Splicer.scala @@ -322,7 +322,7 @@ object Splicer { assert(argss.head.size == argTypes.size) interpretArgsGroup(argss.head, argTypes) ::: interpretArgs(argss.tail, fnType.resType) case fnType: AppliedType if defn.isContextFunctionType(fnType) => - val argTypes :+ resType = fnType.args + val argTypes :+ resType = fnType.args: @unchecked interpretArgsGroup(argss.head, argTypes) ::: interpretArgs(argss.tail, resType) case fnType: PolyType => interpretArgs(argss, fnType.resType) case fnType: ExprType => interpretArgs(argss, fnType.resType) diff --git a/compiler/src/dotty/tools/dotc/transform/Splicing.scala b/compiler/src/dotty/tools/dotc/transform/Splicing.scala index fe0c233173b7..a9b97ebff407 100644 --- a/compiler/src/dotty/tools/dotc/transform/Splicing.scala +++ b/compiler/src/dotty/tools/dotc/transform/Splicing.scala @@ -125,7 +125,7 @@ class Splicing extends MacroTransform: val newSplicedCode2 = Level0QuoteTransformer.transform(newSplicedCode1)(using spliceContext) newSplicedCode2 case tree: TypeDef if tree.symbol.hasAnnotation(defn.QuotedRuntime_SplicedTypeAnnot) => - val tp @ TypeRef(qual: TermRef, _) = tree.rhs.tpe.hiBound + val tp @ TypeRef(qual: TermRef, _) = tree.rhs.tpe.hiBound: @unchecked quotedDefs += tree.symbol val hole = typeHoles.get(qual.symbol) match case Some (hole) => cpy.Hole(hole)(content = EmptyTree) diff --git a/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala b/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala index 8d099d30f880..b0c8605e7dd1 100644 --- a/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala +++ b/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala @@ -101,7 +101,7 @@ class SuperAccessors(thisPhase: DenotTransformer) { * replace by a super accessor call. */ private def transformSuperSelect(sel: Select)(using Context): Tree = { - val Select(sup @ Super(_, mix), name) = sel + val Select(sup @ Super(_, mix), name) = sel: @unchecked val sym = sel.symbol assert(sup.symbol.exists, s"missing symbol in $sel: ${sup.tpe}") val clazz = sup.symbol @@ -171,7 +171,7 @@ class SuperAccessors(thisPhase: DenotTransformer) { /** Transform select node, adding super and protected accessors as needed */ def transformSelect(tree: Tree, targs: List[Tree])(using Context): Tree = { - val sel @ Select(qual, name) = tree + val sel @ Select(qual, name) = tree: @unchecked val sym = sel.symbol /** If an accesses to protected member of a class comes from a trait, diff --git a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala index 3bd3050ee8f1..f07ffaaa8653 100644 --- a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala +++ b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala @@ -456,7 +456,7 @@ class TreeChecker extends Phase with SymTransformer { } override def typedClassDef(cdef: untpd.TypeDef, cls: ClassSymbol)(using Context): Tree = { - val TypeDef(_, impl @ Template(constr, _, _, _)) = cdef + val TypeDef(_, impl @ Template(constr, _, _, _)) = cdef: @unchecked assert(cdef.symbol == cls) assert(impl.symbol.owner == cls) assert(constr.symbol.owner == cls) @@ -575,7 +575,7 @@ class TreeChecker extends Phase with SymTransformer { super.typedPackageDef(tree) override def typedHole(tree: untpd.Hole, pt: Type)(using Context): Tree = { - val tree1 @ Hole(isTermHole, _, args, content, tpt) = super.typedHole(tree, pt) + val tree1 @ Hole(isTermHole, _, args, content, tpt) = super.typedHole(tree, pt): @unchecked // Check result type of the hole if isTermHole then assert(tpt.typeOpt <:< pt) diff --git a/compiler/src/dotty/tools/dotc/transform/TreeMapWithStages.scala b/compiler/src/dotty/tools/dotc/transform/TreeMapWithStages.scala index d4f9e3110a55..b514b8a7bf11 100644 --- a/compiler/src/dotty/tools/dotc/transform/TreeMapWithStages.scala +++ b/compiler/src/dotty/tools/dotc/transform/TreeMapWithStages.scala @@ -62,7 +62,7 @@ abstract class TreeMapWithStages(@constructorOnly ictx: Context) extends TreeMap if body.isTerm then cpy.Apply(quote)(quote.fun, body :: Nil) else - val TypeApply(fun, _) = quote.fun + val TypeApply(fun, _) = quote.fun: @unchecked cpy.Apply(quote)(cpy.TypeApply(quote.fun)(fun, body :: Nil), quote.args) /** Transform the expression splice `splice` which contains the spliced `body`. */ diff --git a/compiler/src/dotty/tools/dotc/transform/TupleOptimizations.scala b/compiler/src/dotty/tools/dotc/transform/TupleOptimizations.scala index 33341995d5b6..6bc2f438eb37 100644 --- a/compiler/src/dotty/tools/dotc/transform/TupleOptimizations.scala +++ b/compiler/src/dotty/tools/dotc/transform/TupleOptimizations.scala @@ -32,7 +32,7 @@ class TupleOptimizations extends MiniPhase with IdentityDenotTransformer { else tree private def transformTupleCons(tree: tpd.Apply)(using Context): Tree = { - val head :: tail :: Nil = tree.args + val head :: tail :: Nil = tree.args: @unchecked defn.tupleTypes(tree.tpe.widenTermRefExpr.dealias) match { case Some(tpes) => // Generate a the tuple directly with TupleN+1.apply @@ -60,7 +60,7 @@ class TupleOptimizations extends MiniPhase with IdentityDenotTransformer { } private def transformTupleTail(tree: tpd.Apply)(using Context): Tree = { - val Apply(_, tup :: Nil) = tree + val Apply(_, tup :: Nil) = tree: @unchecked defn.tupleTypes(tup.tpe.widenTermRefExpr.dealias, MaxTupleArity + 1) match { case Some(tpes) => // Generate a the tuple directly with TupleN-1.apply @@ -103,7 +103,7 @@ class TupleOptimizations extends MiniPhase with IdentityDenotTransformer { } private def transformTupleConcat(tree: tpd.Apply)(using Context): Tree = { - val Apply(_, self :: that :: Nil) = tree + val Apply(_, self :: that :: Nil) = tree: @unchecked (defn.tupleTypes(self.tpe.widenTermRefExpr.dealias), defn.tupleTypes(that.tpe.widenTermRefExpr.dealias)) match { case (Some(tpes1), Some(tpes2)) => // Generate a the tuple directly with TupleN+M.apply @@ -138,7 +138,7 @@ class TupleOptimizations extends MiniPhase with IdentityDenotTransformer { } private def transformTupleApply(tree: tpd.Apply)(using Context): Tree = { - val Apply(_, tup :: nTree :: Nil) = tree + val Apply(_, tup :: nTree :: Nil) = tree: @unchecked (defn.tupleTypes(tup.tpe.widenTermRefExpr.dealias), nTree.tpe) match { case (Some(tpes), nTpe: ConstantType) => // Get the element directly with TupleM._n+1 or TupleXXL.productElement(n) @@ -165,7 +165,7 @@ class TupleOptimizations extends MiniPhase with IdentityDenotTransformer { } private def transformTupleToArray(tree: tpd.Apply)(using Context): Tree = { - val Apply(_, tup :: Nil) = tree + val Apply(_, tup :: Nil) = tree: @unchecked defn.tupleTypes(tup.tpe.widen, MaxTupleArity) match { case Some(tpes) => val size = tpes.size diff --git a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala index 25ea09c3ade4..ed69b863d1af 100644 --- a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala +++ b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala @@ -1124,7 +1124,7 @@ object Semantic { ref match case Select(supert: Super, _) => - val SuperType(thisTp, superTp) = supert.tpe + val SuperType(thisTp, superTp) = supert.tpe: @unchecked val thisValue2 = resolveThis(thisTp.classSymbol.asClass, thisV, klass, ref) Result(thisValue2, errors).call(ref.symbol, args, superTp, expr) @@ -1155,7 +1155,7 @@ object Semantic { name match case OuterSelectName(_, hops) => - val SkolemType(tp) = expr.tpe + val SkolemType(tp) = expr.tpe: @unchecked val outer = resolveOuterSelect(tp.classSymbol.asClass, qualRes.value, hops, source = expr) Result(outer, qualRes.errors) case _ => diff --git a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala index fb4fbd653ee5..56a595780365 100644 --- a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala +++ b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala @@ -592,7 +592,7 @@ class SpaceEngine(using Context) extends SpaceLogic { /** Whether the extractor covers the given type */ def covers(unapp: TermRef, scrutineeTp: Type, argLen: Int): Boolean = SpaceEngine.isIrrefutable(unapp, argLen) || unapp.symbol == defn.TypeTest_unapply && { - val AppliedType(_, _ :: tp :: Nil) = unapp.prefix.widen.dealias + val AppliedType(_, _ :: tp :: Nil) = unapp.prefix.widen.dealias: @unchecked scrutineeTp <:< tp } diff --git a/compiler/src/dotty/tools/dotc/transform/sjs/AddLocalJSFakeNews.scala b/compiler/src/dotty/tools/dotc/transform/sjs/AddLocalJSFakeNews.scala index 9c575c9a9c3c..8851e641122f 100644 --- a/compiler/src/dotty/tools/dotc/transform/sjs/AddLocalJSFakeNews.scala +++ b/compiler/src/dotty/tools/dotc/transform/sjs/AddLocalJSFakeNews.scala @@ -59,7 +59,7 @@ class AddLocalJSFakeNews extends MiniPhase { thisPhase => override def transformApply(tree: Apply)(using Context): Tree = { if (tree.symbol == jsdefn.Runtime_createLocalJSClass) { - val classValueArg :: superClassValueArg :: _ :: Nil = tree.args + val classValueArg :: superClassValueArg :: _ :: Nil = tree.args: @unchecked val cls = classValueArg match { case Literal(constant) if constant.tag == Constants.ClazzTag => constant.typeValue.typeSymbol.asClass diff --git a/compiler/src/dotty/tools/dotc/transform/sjs/PrepJSInterop.scala b/compiler/src/dotty/tools/dotc/transform/sjs/PrepJSInterop.scala index 97bdc138f571..4f7ae5ac60f1 100644 --- a/compiler/src/dotty/tools/dotc/transform/sjs/PrepJSInterop.scala +++ b/compiler/src/dotty/tools/dotc/transform/sjs/PrepJSInterop.scala @@ -1166,7 +1166,7 @@ object PrepJSInterop { Some(result) case _ => // Annotations are stored in reverse order, which we re-reverse now - val result :: duplicates = annots.reverse + val result :: duplicates = annots.reverse: @unchecked for (annot <- duplicates) report.error(badAnnotCountMsg, annot.tree) Some(result) diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index a2c314e12ccf..036edc2683a9 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -517,7 +517,7 @@ trait Applications extends Compatibility { def handlePositional(pnames: List[Name], args: List[Trees.Tree[T]]): List[Trees.Tree[T]] = args match { case (arg: NamedArg @unchecked) :: _ => - val nameAssocs = for (arg @ NamedArg(name, _) <- args) yield (name, arg) + val nameAssocs = for (case arg @ NamedArg(name, _) <- args) yield (name, arg) handleNamed(pnames, args, nameAssocs.toMap, Set()) case arg :: args1 => arg :: handlePositional(if (pnames.isEmpty) Nil else pnames.tail, args1) @@ -1072,7 +1072,7 @@ trait Applications extends Compatibility { throw Error(i"unexpected type.\n fun = $fun,\n methPart(fun) = ${methPart(fun)},\n methPart(fun).tpe = ${methPart(fun).tpe},\n tpe = ${fun.tpe}") def typedNamedArgs(args: List[untpd.Tree])(using Context): List[NamedArg] = - for (arg @ NamedArg(id, argtpt) <- args) yield { + for (case arg @ NamedArg(id, argtpt) <- args) yield { if !Feature.namedTypeArgsEnabled then report.error( i"""Named type arguments are experimental, @@ -1715,7 +1715,7 @@ trait Applications extends Compatibility { } case Nil => previous } - val best :: rest = survivors(alt :: Nil, alts1) + val best :: rest = survivors(alt :: Nil, alts1): @unchecked def asGood(alts: List[TermRef]): List[TermRef] = alts match { case alt :: alts1 => if (compare(alt, best) < 0) asGood(alts1) else alt :: asGood(alts1) diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index c3e9c0fbe560..acbd4f65acc7 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -1356,7 +1356,7 @@ trait Checking { else if (stat.symbol.is(Module) && stat.symbol.linkedClass.isAllOf(EnumCase)) stat match { case TypeDef(_, impl: Template) => - for ((defaultGetter @ + for (case (defaultGetter @ DefDef(DefaultGetterName(nme.CONSTRUCTOR, _), _, _, _)) <- impl.body) check(defaultGetter.rhs) case _ => diff --git a/compiler/src/dotty/tools/dotc/typer/Deriving.scala b/compiler/src/dotty/tools/dotc/typer/Deriving.scala index 77137b46f707..22c73b92802a 100644 --- a/compiler/src/dotty/tools/dotc/typer/Deriving.scala +++ b/compiler/src/dotty/tools/dotc/typer/Deriving.scala @@ -305,7 +305,7 @@ trait Deriving { } def finalize(stat: tpd.TypeDef): tpd.Tree = { - val templ @ Template(_, _, _, _) = stat.rhs + val templ @ Template(_, _, _, _) = stat.rhs: @unchecked tpd.cpy.TypeDef(stat)(rhs = tpd.cpy.Template(templ)(body = templ.body ++ syntheticDefs)) } } diff --git a/compiler/src/dotty/tools/dotc/typer/Dynamic.scala b/compiler/src/dotty/tools/dotc/typer/Dynamic.scala index 23e575c0c2bf..1630ce31e4c6 100644 --- a/compiler/src/dotty/tools/dotc/typer/Dynamic.scala +++ b/compiler/src/dotty/tools/dotc/typer/Dynamic.scala @@ -175,7 +175,7 @@ trait Dynamic { * type */ def handleStructural(tree: Tree)(using Context): Tree = { - val fun @ Select(qual, name) = funPart(tree) + val fun @ Select(qual, name) = funPart(tree): @unchecked val vargss = termArgss(tree) def structuralCall(selectorName: TermName, classOfs: => List[Tree]) = { diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index b1f4eb0b00ba..d768c678d999 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -141,7 +141,7 @@ object Inliner { fn.tpe.widenTermRefExpr match case tp: PolyType => val targBounds = tp.instantiateParamInfos(args.map(_.tpe)) - for (arg, bounds: TypeBounds) <- args.zip(targBounds) if !bounds.contains(arg.tpe) do + for case (arg, bounds: TypeBounds) <- args.zip(targBounds) if !bounds.contains(arg.tpe) do val boundsStr = if bounds == TypeBounds.empty then " <: Any. Note that this type is higher-kinded." else bounds.show @@ -334,7 +334,7 @@ object Inliner { case _ => t } - val Apply(_, codeArg :: Nil) = tree + val Apply(_, codeArg :: Nil) = tree: @unchecked val codeArg1 = stripTyped(codeArg.underlying) val underlyingCodeArg = if Inliner.isInlineable(codeArg1.symbol) then stripTyped(Inliner.inlineCall(codeArg1)) @@ -1747,14 +1747,14 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) { typeMap = new TypeMap() { override def apply(tp: Type): Type = tp match { case tr: TypeRef if tr.prefix.eq(NoPrefix) && typeBindingsSet.contains(tr.symbol) => - val TypeAlias(res) = tr.info + val TypeAlias(res) = tr.info: @unchecked res case tp => mapOver(tp) } }, treeMap = { case ident: Ident if ident.isType && typeBindingsSet.contains(ident.symbol) => - val TypeAlias(r) = ident.symbol.info + val TypeAlias(r) = ident.symbol.info: @unchecked TypeTree(r).withSpan(ident.span) case tree => tree } diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index 79e015e0015c..2bbb41253217 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -478,7 +478,7 @@ class Namer { typer: Typer => annots // can happen if a class has several inaccessible children else { assert(childStart != other.span.start, i"duplicate child annotation $child / $other") - val (prefix, otherAnnot :: rest) = annots.span(_.symbol != defn.ChildAnnot) + val (prefix, otherAnnot :: rest) = annots.span(_.symbol != defn.ChildAnnot): @unchecked prefix ::: otherAnnot :: insertInto(rest) } case _ => @@ -516,7 +516,7 @@ class Namer { typer: Typer => /** Remove the subtree `tree` from the expanded tree of `mdef` */ def removeInExpanded(mdef: Tree, tree: Tree): Unit = { - val Thicket(trees) = expanded(mdef) + val Thicket(trees) = expanded(mdef): @unchecked mdef.putAttachment(ExpandedTree, Thicket(trees.filter(_ != tree))) } @@ -532,7 +532,7 @@ class Namer { typer: Typer => */ def mergeModuleClass(mdef: Tree, modCls: TypeDef, fromCls: TypeDef): TypeDef = { var res: TypeDef | Null = null - val Thicket(trees) = expanded(mdef) + val Thicket(trees) = expanded(mdef): @unchecked val merged = trees.map { tree => if (tree == modCls) { val fromTempl = fromCls.rhs.asInstanceOf[Template] @@ -1060,7 +1060,7 @@ class Namer { typer: Typer => /** info to be used temporarily while completing the class, to avoid cyclic references. */ private var tempInfo: TempClassInfo | Null = null - val TypeDef(name, impl @ Template(constr, _, self, _)) = original + val TypeDef(name, impl @ Template(constr, _, self, _)) = original: @unchecked private val (params, rest): (List[Tree], List[Tree]) = impl.body.span { case td: TypeDef => td.mods.is(Param) @@ -1142,7 +1142,7 @@ class Namer { typer: Typer => // Note: in this branch we use the assumptions // that `prefss.head` corresponds to `mt.paramInfos` and // that `prefss.tail` corresponds to `mt.resType` - val init :+ vararg = prefss.head + val init :+ vararg = prefss.head: @unchecked val prefs = init :+ ctx.typeAssigner.seqToRepeated(vararg) adaptForwarderParams(prefs :: acc, mt.resType, prefss.tail) case mt: MethodOrPoly => diff --git a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala index 5f14352a1fb3..783c03cba812 100644 --- a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala +++ b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala @@ -121,7 +121,7 @@ trait QuotesAndSplices { */ def typedAppliedSplice(tree: untpd.Apply, pt: Type)(using Context): Tree = { assert(ctx.mode.is(Mode.QuotedPattern)) - val untpd.Apply(splice: untpd.Splice, args) = tree + val untpd.Apply(splice: untpd.Splice, args) = tree: @unchecked if !isFullyDefined(pt, ForceDegree.flipBottom) then report.error(i"Type must be fully defined.", splice.srcPos) tree.withType(UnspecifiedErrorType) diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index 0de3a03b167e..11131929488f 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -70,7 +70,7 @@ object RefChecks { // Check for doomed attempt to overload applyDynamic if (clazz derivesFrom defn.DynamicClass) - for ((_, m1 :: m2 :: _) <- (clazz.info member nme.applyDynamic).alternatives groupBy (_.symbol.typeParams.length)) + for (case (_, m1 :: m2 :: _) <- (clazz.info member nme.applyDynamic).alternatives groupBy (_.symbol.typeParams.length)) report.error("implementation restriction: applyDynamic cannot be overloaded except by methods with different numbers of type parameters, e.g. applyDynamic[T1](method: String)(arg: T1) and applyDynamic[T1, T2](method: String)(arg1: T1, arg2: T2)", m1.symbol.srcPos) } @@ -1015,7 +1015,7 @@ object RefChecks { ErrorReporting.substitutableTypeSymbolsInScope(sd.symbol).map(_.denot.name.show) for annotation <- sd.getAnnotation(defn.ImplicitNotFoundAnnot) - PositionedStringLiteralArgument(msg, span) <- annotation.argument(0) + case PositionedStringLiteralArgument(msg, span) <- annotation.argument(0) do forEachTypeVariableReferenceIn(msg) { case (ref, start) => if !substitutableTypesNames.contains(ref) then reportInvalidReference(span, ref, start, sd) diff --git a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala index c7adca68e2af..1899eb8dc9e2 100644 --- a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala @@ -60,7 +60,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context): else // Generate SAM: (s: ) => if s.isInstanceOf[] then Some(s.asInstanceOf[s.type & ]) else None def body(args: List[Tree]): Tree = { - val arg :: Nil = args + val arg :: Nil = args: @unchecked val t = arg.tpe & tp2 If( arg.isInstance(tp2), diff --git a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala index 80068d8632e6..32e2d649b5dc 100644 --- a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -305,7 +305,7 @@ trait TypeAssigner { // Type arguments which are specified by name (immutable after this first loop) val namedArgMap = new mutable.HashMap[Name, Type] - for (NamedArg(name, arg) <- args) + for (case NamedArg(name, arg) <- args) if (namedArgMap.contains(name)) report.error(DuplicateNamedTypeParameter(name), arg.srcPos) else if (!paramNames.contains(name)) diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 7ece68cea480..9cfae53dace9 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1145,7 +1145,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer val thenp0 = typed(tree.thenp, branchPt)(using cond1.nullableContextIf(true)) val elsep0 = typed(tree.elsep, branchPt)(using cond1.nullableContextIf(false)) thenp0 :: elsep0 :: Nil - } + }: @unchecked assignType(cpy.If(tree)(cond1, thenp1, elsep1), thenp1, elsep1) def thenPathInfo = cond1.notNullInfoIf(true).seq(result.thenp.notNullInfo) @@ -1313,7 +1313,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer } def typedFunctionValue(tree: untpd.Function, pt: Type)(using Context): Tree = { - val untpd.Function(params: List[untpd.ValDef] @unchecked, _) = tree + val untpd.Function(params: List[untpd.ValDef] @unchecked, _) = tree: @unchecked val isContextual = tree match { case tree: untpd.FunctionWithMods => tree.mods.is(Given) @@ -1582,7 +1582,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer // check `pat` here and throw away the result. val gadtCtx: Context = ctx.fresh.setFreshGADTBounds val pat1 = typedPattern(pat, selType)(using gadtCtx) - val Typed(_, tpt) = tpd.unbind(tpd.unsplice(pat1)) + val Typed(_, tpt) = tpd.unbind(tpd.unsplice(pat1)): @unchecked instantiateMatchTypeProto(pat1, pt) match { case defn.MatchCase(patternTp, _) => tpt.tpe frozen_=:= patternTp case _ => false @@ -1841,7 +1841,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer val cases1 = typedCases(tree.cases, EmptyTree, defn.ThrowableType, pt.dropIfProto) val expr1 = typed(addCanThrowCapabilities(tree.expr, cases1), pt.dropIfProto) expr1 :: cases1 - } + }: @unchecked val finalizer1 = typed(tree.finalizer, defn.UnitType) val cases2 = cases2x.asInstanceOf[List[CaseDef]] assignType(cpy.Try(tree)(expr2, cases2, finalizer1), expr2, cases2) @@ -1932,7 +1932,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer val tpt1 = if (tree.tpt.isEmpty) TypeTree(defn.ObjectType) else typedAheadType(tree.tpt) val refineClsDef = desugar.refinedTypeToClass(tpt1, tree.refinements).withSpan(tree.span) val refineCls = createSymbol(refineClsDef).asClass - val TypeDef(_, impl: Template) = typed(refineClsDef) + val TypeDef(_, impl: Template) = typed(refineClsDef): @unchecked val refinements1 = impl.body assert(tree.refinements.hasSameLengthAs(refinements1), i"${tree.refinements}%, % > $refinements1%, %") val seen = mutable.Set[Symbol]() @@ -2374,7 +2374,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer def typedClassDef(cdef: untpd.TypeDef, cls: ClassSymbol)(using Context): Tree = { if (!cls.info.isInstanceOf[ClassInfo]) return EmptyTree.assertingErrorsReported - val TypeDef(name, impl @ Template(constr, _, self, _)) = cdef + val TypeDef(name, impl @ Template(constr, _, self, _)) = cdef: @unchecked val parents = impl.parents val superCtx = ctx.superCallContext @@ -2687,7 +2687,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer } def typedAsFunction(tree: untpd.PostfixOp, pt: Type)(using Context): Tree = { - val untpd.PostfixOp(qual, Ident(nme.WILDCARD)) = tree + val untpd.PostfixOp(qual, Ident(nme.WILDCARD)) = tree: @unchecked val pt1 = if (defn.isFunctionType(pt)) pt else AnyFunctionProto val nestedCtx = ctx.fresh.setNewTyperState() val res = typed(qual, pt1)(using nestedCtx) @@ -2947,7 +2947,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer tree protected def makeContextualFunction(tree: untpd.Tree, pt: Type)(using Context): Tree = { - val defn.FunctionOf(formals, _, true, _) = pt.dropDependentRefinement + val defn.FunctionOf(formals, _, true, _) = pt.dropDependentRefinement: @unchecked // The getter of default parameters may reach here. // Given the code below @@ -3989,7 +3989,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer /** Convert constructor proxy reference to a new expression */ def newExpr = - val Select(qual, nme.apply) = tree; @unchecked + val Select(qual, nme.apply) = tree: @unchecked val tycon = tree.tpe.widen.finalResultType.underlyingClassRef(refinementOK = false) val tpt = qual match case Ident(name) => diff --git a/compiler/src/dotty/tools/dotc/util/ParsedComment.scala b/compiler/src/dotty/tools/dotc/util/ParsedComment.scala index 1a773f179dc1..ac724f7e336f 100644 --- a/compiler/src/dotty/tools/dotc/util/ParsedComment.scala +++ b/compiler/src/dotty/tools/dotc/util/ParsedComment.scala @@ -140,7 +140,7 @@ object ParsedComment { */ private def toDescriptionList(ctx: Context, items: List[String]): String = inContext(ctx) { val formattedItems = items.map { p => - val name :: rest = p.split(" ", 2).toList + val name :: rest = p.split(" ", 2).toList: @unchecked s"${bold(name)} ${rest.mkString("").trim}" } toMarkdownList(ctx, formattedItems) diff --git a/compiler/src/dotty/tools/repl/CollectTopLevelImports.scala b/compiler/src/dotty/tools/repl/CollectTopLevelImports.scala index f78729d81533..d539c1986f8d 100644 --- a/compiler/src/dotty/tools/repl/CollectTopLevelImports.scala +++ b/compiler/src/dotty/tools/repl/CollectTopLevelImports.scala @@ -19,7 +19,7 @@ class CollectTopLevelImports extends Phase { def run(using Context): Unit = { def topLevelImports(tree: Tree) = { - val PackageDef(_, _ :: TypeDef(_, rhs: Template) :: _) = tree + val PackageDef(_, _ :: TypeDef(_, rhs: Template) :: _) = tree: @unchecked rhs.body.collect { case tree: Import => tree } } diff --git a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala index da560ab6e240..30f4dc29aeea 100644 --- a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala +++ b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala @@ -236,7 +236,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler tpd.ClassDefWithParents(cls.asClass, ctr, parents, body) def copy(original: Tree)(name: String, constr: DefDef, parents: List[Tree], selfOpt: Option[ValDef], body: List[Statement]): ClassDef = { - val dotc.ast.Trees.TypeDef(_, originalImpl: tpd.Template) = original + val dotc.ast.Trees.TypeDef(_, originalImpl: tpd.Template) = original: @unchecked tpd.cpy.TypeDef(original)(name.toTypeName, tpd.cpy.Template(originalImpl)(constr, parents, derived = Nil, selfOpt.getOrElse(tpd.EmptyValDef), body)) } def unapply(cdef: ClassDef): (String, DefDef, List[Tree /* Term | TypeTree */], Option[ValDef], List[Statement]) = @@ -1014,7 +1014,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler def qualifier: Term = self.qualifier def name: String = self.name.toString def level: Int = - val NameKinds.OuterSelectName(_, levels) = self.name + val NameKinds.OuterSelectName(_, levels) = self.name: @unchecked levels end extension end SelectOuterMethods diff --git a/compiler/src/scala/quoted/runtime/impl/printers/SourceCode.scala b/compiler/src/scala/quoted/runtime/impl/printers/SourceCode.scala index cde4853ff0fc..5d61902fbedd 100644 --- a/compiler/src/scala/quoted/runtime/impl/printers/SourceCode.scala +++ b/compiler/src/scala/quoted/runtime/impl/printers/SourceCode.scala @@ -230,7 +230,7 @@ object SourceCode { this += " {" indented { if (printSelf) { - val Some(ValDef(name, tpt, _)) = self + val Some(ValDef(name, tpt, _)) = self: @unchecked indented { val name1 = if (name == "_") "this" else name this += " " += highlightValDef(name1) += ": " @@ -848,7 +848,7 @@ object SourceCode { val name = splicedName(arg.symbol).getOrElse(arg.symbol.name) val sym = arg.symbol.owner if sym.isDefDef && sym.name == "" then - val ClassDef(_, _, _, _, body) = sym.owner.tree + val ClassDef(_, _, _, _, body) = sym.owner.tree: @unchecked body.collectFirst { case vdef @ ValDef(`name`, _, _) if vdef.symbol.flags.is(Flags.ParamAccessor) => if (!vdef.symbol.flags.is(Flags.Local)) { @@ -1036,10 +1036,10 @@ object SourceCode { inSquare(printTrees(args, ", ")) case Annotated(tpt, annot) => - val Annotation(ref, args) = annot + val Annotation(ref, args) = annot: @unchecked ref.tpe match { case tpe: TypeRef if tpe.typeSymbol == Symbol.requiredClass("scala.annotation.internal.Repeated") => - val Types.Sequence(tp) = tpt.tpe + val Types.Sequence(tp) = tpt.tpe: @unchecked printType(tp) this += highlightTypeDef("*") case _ => @@ -1145,7 +1145,7 @@ object SourceCode { } case AnnotatedType(tp, annot) => - val Annotation(ref, args) = annot + val Annotation(ref, args) = annot: @unchecked printType(tp) this += " " printAnnotation(annot) @@ -1262,7 +1262,7 @@ object SourceCode { } private def printAnnotation(annot: Term)(using elideThis: Option[Symbol]): this.type = { - val Annotation(ref, args) = annot + val Annotation(ref, args) = annot: @unchecked this += "@" printTypeTree(ref) if (args.isEmpty) @@ -1402,7 +1402,7 @@ object SourceCode { this += name += "." case _ => } - val TypeRef(prefix, name) = tp + val TypeRef(prefix, name) = tp: @unchecked printClassPrefix(prefix) this += name } diff --git a/library/src/scala/quoted/ExprMap.scala b/library/src/scala/quoted/ExprMap.scala index 94979724d20d..86ec1e72bb9f 100644 --- a/library/src/scala/quoted/ExprMap.scala +++ b/library/src/scala/quoted/ExprMap.scala @@ -48,7 +48,7 @@ trait ExprMap: case Super(qual, mix) => tree case tree @ Apply(fun, args) => - val MethodType(_, tpes, _) = fun.tpe.widen + val MethodType(_, tpes, _) = fun.tpe.widen: @unchecked Apply.copy(tree)(transformTerm(fun, TypeRepr.of[Any])(owner), transformTerms(args, tpes)(owner)) case TypeApply(fun, args) => TypeApply.copy(tree)(transformTerm(fun, TypeRepr.of[Any])(owner), args) @@ -127,7 +127,7 @@ trait ExprMap: def transformTerms(trees: List[Term], tpes: List[TypeRepr])(owner: Symbol): List[Term] = var tpes2 = tpes // TODO use proper zipConserve trees.mapConserve{ x => - val tpe :: tail = tpes2 + val tpe :: tail = tpes2: @unchecked tpes2 = tail transformTerm(x, tpe)(owner) } diff --git a/library/src/scala/quoted/Quotes.scala b/library/src/scala/quoted/Quotes.scala index ce524f7166a1..7e9fc6daa1ed 100644 --- a/library/src/scala/quoted/Quotes.scala +++ b/library/src/scala/quoted/Quotes.scala @@ -4716,7 +4716,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => val owner = tree.symbol TypeDef.copy(tree)(tree.name, transformTree(tree.rhs)(owner)) case tree: ClassDef => - val constructor @ DefDef(_, _, _, _) = transformStatement(tree.constructor)(tree.symbol) + val constructor @ DefDef(_, _, _, _) = transformStatement(tree.constructor)(tree.symbol): @unchecked val parents = tree.parents.map(transformTree(_)(tree.symbol)) val self = tree.self.map { slf => transformStatement(slf)(tree.symbol) match diff --git a/scaladoc/src/dotty/tools/scaladoc/renderers/MemberRenderer.scala b/scaladoc/src/dotty/tools/scaladoc/renderers/MemberRenderer.scala index 616599c07152..75d8ac4ee756 100644 --- a/scaladoc/src/dotty/tools/scaladoc/renderers/MemberRenderer.scala +++ b/scaladoc/src/dotty/tools/scaladoc/renderers/MemberRenderer.scala @@ -135,7 +135,7 @@ class MemberRenderer(signatureRenderer: SignatureRenderer)(using DocContext) ext val rawBuilder = ScalaSignatureProvider.rawSignature(member, InlineSignatureBuilder())() val inlineBuilder = rawBuilder.asInstanceOf[InlineSignatureBuilder] - val kind :: modifiersRevered = inlineBuilder.preName + val kind :: modifiersRevered = inlineBuilder.preName: @unchecked val signature = inlineBuilder.names.reverse Seq( div(cls := "signature")( diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/SelfTypePrinter.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/SelfTypePrinter.scala index 9a12a1e93dcc..2cfbbed126b2 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/SelfTypePrinter.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/SelfTypePrinter.scala @@ -40,7 +40,7 @@ class SelfTypePrinter(using _ctx: Context) extends RefinedPrinter(_ctx): override def toText(tp: Type): Text = tp match case tp: RefinedType => val parent :: (refined: List[RefinedType @unchecked]) = - refinementChain(tp).reverse + refinementChain(tp).reverse: @unchecked toTextLocal(parent) case tp => super.toText(tp) diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/ClassLikeSupport.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/ClassLikeSupport.scala index 1e855e6e541a..3432b2caeea1 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/ClassLikeSupport.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/ClassLikeSupport.scala @@ -514,7 +514,7 @@ trait ClassLikeSupport: case _ => Nil def nameForRef(ref: ParamRef): String = - val PolyType(names, _, _) = ref.binder + val PolyType(names, _, _) = ref.binder: @unchecked names(ref.paramNum) val (paramsThatLookLikeContextBounds, contextBounds) = diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/wiki/Parser.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/wiki/Parser.scala index bd39abb7d41f..dd3187fb5346 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/wiki/Parser.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/wiki/Parser.scala @@ -358,7 +358,7 @@ final class Parser( reportError("Fixing missing delimiter row") Row(Cell(Paragraph(Text("-")) :: Nil) :: Nil) :: Nil } - } + }: @unchecked if (delimiterRow.cells.isEmpty) sys.error("TODO: Handle table with empty delimiter row") From 56c69bd426e4e656d02fe8f33f8019ce783dea95 Mon Sep 17 00:00:00 2001 From: Tom Grigg Date: Mon, 4 Apr 2022 13:10:52 -0700 Subject: [PATCH 07/12] workaround for lampepfl/dotty#14821 --- library/src/scala/quoted/Quotes.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/src/scala/quoted/Quotes.scala b/library/src/scala/quoted/Quotes.scala index 7e9fc6daa1ed..8aa203896818 100644 --- a/library/src/scala/quoted/Quotes.scala +++ b/library/src/scala/quoted/Quotes.scala @@ -4723,7 +4723,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => case self: ValDef => self } val body = tree.body.map(transformStatement(_)(tree.symbol)) - ClassDef.copy(tree)(tree.name, constructor, parents, self, body) + ClassDef.copy(tree)(tree.name, constructor.asInstanceOf[DefDef], parents, self, body) // cast as workaround for lampepfl/dotty#14821. TODO remove when referenceVersion >= 3.2.0-RC1 case tree: Import => Import.copy(tree)(transformTerm(tree.expr)(owner), tree.selectors) case tree: Export => From 7eb227fdc95b063e2af7840ea107da3de763132c Mon Sep 17 00:00:00 2001 From: Tom Grigg Date: Tue, 18 Jan 2022 14:15:19 -0800 Subject: [PATCH 08/12] Adapt tests for strict pattern binding warnings --- compiler/test-resources/repl/i3536_bind | 2 +- .../test-resources/repl/i3536_patterndef_some | 2 +- compiler/test-resources/repl/i3966 | 2 +- compiler/test-resources/repl/patdef | 2 +- .../dotty/tools/dotc/TastyBootstrapTests.scala | 2 +- .../test/dotty/tools/dotc/ast/DesugarTests.scala | 2 +- .../dotty/tools/dotc/printing/PrinterTests.scala | 2 +- .../reporting/UserDefinedErrorMessages.scala | 10 +++++----- .../dotty/tools/repl/ReplCompilerTests.scala | 8 ++++---- .../tasty/comments/MemberLookupTests.scala | 10 +++++----- .../tasty/comments/QueryParserTests.scala | 4 ++-- tests/neg-macros/i6432/Macro_1.scala | 2 +- tests/neg-macros/i6432b/Macro_1.scala | 2 +- tests/neg/t5702-neg-bad-and-wild.check | 16 ++++++++++++++++ tests/patmat/for.scala | 2 +- tests/pos-special/fatal-warnings/i6621.scala | 2 +- tests/pos/i14587.hard-union-tuples.scala | 3 ++- tests/semanticdb/expect/Synthetic.expect.scala | 6 +++--- tests/semanticdb/expect/Synthetic.scala | 6 +++--- 19 files changed, 51 insertions(+), 34 deletions(-) diff --git a/compiler/test-resources/repl/i3536_bind b/compiler/test-resources/repl/i3536_bind index 96ccdce81356..e1504cc5af3a 100644 --- a/compiler/test-resources/repl/i3536_bind +++ b/compiler/test-resources/repl/i3536_bind @@ -1,4 +1,4 @@ -scala> val res10 @ Some(_) = Option(1) +scala> val res10 @ Some(_) = Option(1): @unchecked val res10: Some[Int] = Some(1) scala> res10 val res11: Some[Int] = Some(1) diff --git a/compiler/test-resources/repl/i3536_patterndef_some b/compiler/test-resources/repl/i3536_patterndef_some index 24c8736b57b9..7492c16288e3 100644 --- a/compiler/test-resources/repl/i3536_patterndef_some +++ b/compiler/test-resources/repl/i3536_patterndef_some @@ -1,4 +1,4 @@ -scala> val Some((res40, res41)) = Option((1, 0)) +scala> val Some((res40, res41)) = Option((1, 0)): @unchecked val res40: Int = 1 val res41: Int = 0 scala> res40 diff --git a/compiler/test-resources/repl/i3966 b/compiler/test-resources/repl/i3966 index 9002c1607405..204a7685f854 100644 --- a/compiler/test-resources/repl/i3966 +++ b/compiler/test-resources/repl/i3966 @@ -1,2 +1,2 @@ -scala> val List(x: _*) = List(1, 2) +scala> val List(x: _*) = List(1, 2): @unchecked val x: Seq[Int] = List(1, 2) diff --git a/compiler/test-resources/repl/patdef b/compiler/test-resources/repl/patdef index 12ba13bcd6d5..7bd06483934a 100644 --- a/compiler/test-resources/repl/patdef +++ b/compiler/test-resources/repl/patdef @@ -1,7 +1,7 @@ scala> val Const, x = 0 val Const: Int = 0 val x: Int = 0 -scala> val (Const, List(`x`, _, a), b) = (0, List(0, 1337, 1), 2) +scala> val (Const, List(`x`, _, a), b) = (0, List(0, 1337, 1), 2): @unchecked val a: Int = 1 val b: Int = 2 scala> val a@b = 0 diff --git a/compiler/test/dotty/tools/dotc/TastyBootstrapTests.scala b/compiler/test/dotty/tools/dotc/TastyBootstrapTests.scala index 3164e11e9b2f..c95630144496 100644 --- a/compiler/test/dotty/tools/dotc/TastyBootstrapTests.scala +++ b/compiler/test/dotty/tools/dotc/TastyBootstrapTests.scala @@ -60,7 +60,7 @@ class TastyBootstrapTests { compileList("lib", librarySources, defaultOptions.and("-Ycheck-reentrant", "-language:experimental.erasedDefinitions", // support declaration of scala.compiletime.erasedValue - // "-source", "future", // TODO: re-enable once we allow : @unchecked in pattern definitions. Right now, lots of narrowing pattern definitions fail. + // "-source", "future", // TODO: re-enable once library uses updated syntax for vararg splices, wildcard imports, and import renaming ))(libGroup) val tastyCoreSources = sources(Paths.get("tasty/src")) diff --git a/compiler/test/dotty/tools/dotc/ast/DesugarTests.scala b/compiler/test/dotty/tools/dotc/ast/DesugarTests.scala index dc736596ed9b..43b71f191bd2 100644 --- a/compiler/test/dotty/tools/dotc/ast/DesugarTests.scala +++ b/compiler/test/dotty/tools/dotc/ast/DesugarTests.scala @@ -26,7 +26,7 @@ class DesugarTests extends DottyTest { val ccTree = tree.find(tree => tree.symbol.name == typeName("Foo")).get val List(_, foo) = defPath(ccTree.symbol, tree).map(_.symbol.info) - val x :: y :: rest = foo.decls.toList + val x :: y :: rest = foo.decls.toList: @unchecked // Make sure we extracted the correct values from foo: assert(x.name == termName("x")) diff --git a/compiler/test/dotty/tools/dotc/printing/PrinterTests.scala b/compiler/test/dotty/tools/dotc/printing/PrinterTests.scala index 23054cdf0dfb..64049453b595 100644 --- a/compiler/test/dotty/tools/dotc/printing/PrinterTests.scala +++ b/compiler/test/dotty/tools/dotc/printing/PrinterTests.scala @@ -47,7 +47,7 @@ class PrinterTests extends DottyTest { checkCompile("typer", source) { (tree, context) => given Context = context - val bar @ Trees.DefDef(_, _, _, _) = tree.find(tree => tree.symbol.name == termName("bar2")).get + val bar @ Trees.DefDef(_, _, _, _) = tree.find(tree => tree.symbol.name == termName("bar2")).get: @unchecked assertEquals("Int & (Boolean | String)", bar.tpt.show) } } diff --git a/compiler/test/dotty/tools/dotc/reporting/UserDefinedErrorMessages.scala b/compiler/test/dotty/tools/dotc/reporting/UserDefinedErrorMessages.scala index bd72ac6c6288..4d73b0d88b55 100644 --- a/compiler/test/dotty/tools/dotc/reporting/UserDefinedErrorMessages.scala +++ b/compiler/test/dotty/tools/dotc/reporting/UserDefinedErrorMessages.scala @@ -26,7 +26,7 @@ class UserDefinedErrorMessages extends ErrorMessagesTest { given Context = itcx assertMessageCount(1, messages) - val (m: NoExplanation) :: Nil = messages + val (m: NoExplanation) :: Nil = messages: @unchecked assertEquals(m.msg, "Could not prove Int =!= Int") } @@ -50,7 +50,7 @@ class UserDefinedErrorMessages extends ErrorMessagesTest { given Context = itcx assertMessageCount(1, messages) - val (m: NoExplanation) :: Nil = messages + val (m: NoExplanation) :: Nil = messages: @unchecked assertEquals(m.msg, "Could not prove Int =!= Int") } @@ -75,7 +75,7 @@ class UserDefinedErrorMessages extends ErrorMessagesTest { given Context = itcx assertMessageCount(1, messages) - val (m: NoExplanation) :: Nil = messages + val (m: NoExplanation) :: Nil = messages: @unchecked assertEquals(m.msg, "Could not prove Int =!= Int") } @@ -97,7 +97,7 @@ class UserDefinedErrorMessages extends ErrorMessagesTest { given Context = itcx assertMessageCount(1, messages) - val (m: NoExplanation) :: Nil = messages + val (m: NoExplanation) :: Nil = messages: @unchecked assertEquals(m.msg, "msg A=Any") } @@ -119,7 +119,7 @@ class UserDefinedErrorMessages extends ErrorMessagesTest { given Context = itcx assertMessageCount(1, messages) - val (m: NoExplanation) :: Nil = messages + val (m: NoExplanation) :: Nil = messages: @unchecked assertEquals(m.msg, "msg A=Any") } diff --git a/compiler/test/dotty/tools/repl/ReplCompilerTests.scala b/compiler/test/dotty/tools/repl/ReplCompilerTests.scala index 963f269af8a6..866647476888 100644 --- a/compiler/test/dotty/tools/repl/ReplCompilerTests.scala +++ b/compiler/test/dotty/tools/repl/ReplCompilerTests.scala @@ -213,18 +213,18 @@ class ReplCompilerTests extends ReplTest: } @Test def `i10214 must show classic MatchError` = initially { - run("val 1 = 2") + run("val 1 = 2: @unchecked") assertEquals("scala.MatchError: 2 (of class java.lang.Integer)", storedOutput().linesIterator.next()) } @Test def `i10214 must show useful regex MatchError` = initially { run("""val r = raw"\d+".r""") } andThen { - run("""val r() = "abc"""") + run("""val r() = "abc": @unchecked""") assertEquals("scala.MatchError: abc (of class java.lang.String)", storedOutput().linesIterator.drop(1).next()) } @Test def `i10214 must show MatchError on literal type` = initially { - run("val (x: 1) = 2") + run("val (x: 1) = 2: @unchecked") assertEquals("scala.MatchError: 2 (of class java.lang.Integer)", storedOutput().linesIterator.next()) } @Test def `i12920 must truncate stack trace to user code` = initially { @@ -328,7 +328,7 @@ class ReplCompilerTests extends ReplTest: } @Test def i14473 = initially { - run("""val (x,y) = if true then "hi" else (42,17)""") + run("""val (x,y) = (if true then "hi" else (42,17)): @unchecked""") val all = lines() assertEquals(2, all.length) assertEquals("scala.MatchError: hi (of class java.lang.String)", all.head) diff --git a/scaladoc/test/dotty/tools/scaladoc/tasty/comments/MemberLookupTests.scala b/scaladoc/test/dotty/tools/scaladoc/tasty/comments/MemberLookupTests.scala index 0b9b88fa5bb8..c246401c75fc 100644 --- a/scaladoc/test/dotty/tools/scaladoc/tasty/comments/MemberLookupTests.scala +++ b/scaladoc/test/dotty/tools/scaladoc/tasty/comments/MemberLookupTests.scala @@ -60,7 +60,7 @@ class LookupTestCases[Q <: Quotes](val q: Quotes) { val target = wrappedTarget.symbol val lookupRes = MemberLookup.lookupOpt(parseQuery(query), None) assertTrue(s"Couldn't look up: $query", lookupRes.nonEmpty) - val Some((lookedUp, _, _)) = lookupRes + val Some((lookedUp, _, _)) = lookupRes: @unchecked assertSame(query, target, lookedUp) } @@ -83,7 +83,7 @@ class LookupTestCases[Q <: Quotes](val q: Quotes) { val target = sym.symbol val lookupRes = MemberLookup.lookupOpt(parseQuery(query), None) assertTrue(s"Couldn't look up: $query", lookupRes.nonEmpty) - val Some((_ , _, Some(owner))) = lookupRes + val Some((_ , _, Some(owner))) = lookupRes: @unchecked assertSame(query, target, owner) } } @@ -102,7 +102,7 @@ class LookupTestCases[Q <: Quotes](val q: Quotes) { val lookupRes = MemberLookup.lookupOpt(parseQuery(query), Some(cls("scala.=:=").symbol)) assertTrue(s"Couldn't look up: $query", lookupRes.nonEmpty) println(lookupRes) - val Some((_ , _, owner)) = lookupRes + val Some((_ , _, owner)) = lookupRes: @unchecked assertSame(query, None, owner) } } @@ -161,7 +161,7 @@ class LookupTestCases[Q <: Quotes](val q: Quotes) { ) cases.foreach { case ((Sym(owner), query), Sym(target)) => - val Some((lookedUp, _, _)) = MemberLookup.lookup(parseQuery(query), owner) + val Some((lookedUp, _, _)) = MemberLookup.lookup(parseQuery(query), owner): @unchecked assertSame(s"$owner / $query", target, lookedUp) } } @@ -176,7 +176,7 @@ class LookupTestCases[Q <: Quotes](val q: Quotes) { given q.type = q def parseQuery(query: String): Query = { - val Right(parsed) = QueryParser(query).tryReadQuery() + val Right(parsed) = QueryParser(query).tryReadQuery(): @unchecked parsed } diff --git a/scaladoc/test/dotty/tools/scaladoc/tasty/comments/QueryParserTests.scala b/scaladoc/test/dotty/tools/scaladoc/tasty/comments/QueryParserTests.scala index 676a11348a5f..0d33a9363bac 100644 --- a/scaladoc/test/dotty/tools/scaladoc/tasty/comments/QueryParserTests.scala +++ b/scaladoc/test/dotty/tools/scaladoc/tasty/comments/QueryParserTests.scala @@ -64,12 +64,12 @@ class QueryParserTests { private def parse(input: String) = QueryParser(input).tryReadQuery() private def testSuccess(input: String, expected: Query) = { - val Right(got) = parse(input) + val Right(got) = parse(input): @unchecked assertEquals(expected, got) } private def testFailAt(input: String, char: Int) = { - val Left(err) = parse(input) + val Left(err) = parse(input): @unchecked assertEquals(s"expected to fail at $char : $input", char, err.at) } } diff --git a/tests/neg-macros/i6432/Macro_1.scala b/tests/neg-macros/i6432/Macro_1.scala index e2628fd45f7f..992cdc62ceaf 100644 --- a/tests/neg-macros/i6432/Macro_1.scala +++ b/tests/neg-macros/i6432/Macro_1.scala @@ -9,7 +9,7 @@ object Macro { import quotes.reflect.* sc match { case '{ StringContext(${Varargs(parts)}*) } => - for (part @ Expr(s) <- parts) + for (case part @ Expr(s) <- parts) report.error(s, part.asTerm.pos) } '{} diff --git a/tests/neg-macros/i6432b/Macro_1.scala b/tests/neg-macros/i6432b/Macro_1.scala index e2628fd45f7f..992cdc62ceaf 100644 --- a/tests/neg-macros/i6432b/Macro_1.scala +++ b/tests/neg-macros/i6432b/Macro_1.scala @@ -9,7 +9,7 @@ object Macro { import quotes.reflect.* sc match { case '{ StringContext(${Varargs(parts)}*) } => - for (part @ Expr(s) <- parts) + for (case part @ Expr(s) <- parts) report.error(s, part.asTerm.pos) } '{} diff --git a/tests/neg/t5702-neg-bad-and-wild.check b/tests/neg/t5702-neg-bad-and-wild.check index 623bf3002cca..f6d761a6726f 100644 --- a/tests/neg/t5702-neg-bad-and-wild.check +++ b/tests/neg/t5702-neg-bad-and-wild.check @@ -56,3 +56,19 @@ | Recursive value $1$ needs type | | longer explanation available when compiling with `-explain` +-- Warning: tests/neg/t5702-neg-bad-and-wild.scala:22:20 --------------------------------------------------------------- +22 | val K(x @ _*) = k + | ^ + | pattern's type Int* does not match the right hand side expression's type Int + | + | If the narrowing is intentional, this can be communicated by adding `: @unchecked` after the expression, + | which may result in a MatchError at runtime. + | This patch can be rewritten automatically under -rewrite -source 3.2-migration. +-- Warning: tests/neg/t5702-neg-bad-and-wild.scala:25:20 --------------------------------------------------------------- +25 | val (b, _ * ) = (5,6) // ok + | ^^^^^ + | pattern's type Int* does not match the right hand side expression's type Int + | + | If the narrowing is intentional, this can be communicated by adding `: @unchecked` after the expression, + | which may result in a MatchError at runtime. + | This patch can be rewritten automatically under -rewrite -source 3.2-migration. diff --git a/tests/patmat/for.scala b/tests/patmat/for.scala index 4c2ed262fc30..14e5de351212 100644 --- a/tests/patmat/for.scala +++ b/tests/patmat/for.scala @@ -3,5 +3,5 @@ object Test { for ((a, b) <- l) yield a } - def bar(xs: List[(Int, List[Int])]): Unit = for ( (_, x :: y :: xs) <- xs) yield x + def bar(xs: List[(Int, List[Int])]): Unit = for (case (_, x :: y :: xs) <- xs) yield x } \ No newline at end of file diff --git a/tests/pos-special/fatal-warnings/i6621.scala b/tests/pos-special/fatal-warnings/i6621.scala index a006c1254ae0..92362a004530 100644 --- a/tests/pos-special/fatal-warnings/i6621.scala +++ b/tests/pos-special/fatal-warnings/i6621.scala @@ -4,5 +4,5 @@ object Unapply { } object Test { - val Unapply(x, y) = "" + val Unapply(x, y) = "": @unchecked } diff --git a/tests/pos/i14587.hard-union-tuples.scala b/tests/pos/i14587.hard-union-tuples.scala index 2d4ebcf93cc0..e1a086655e5f 100644 --- a/tests/pos/i14587.hard-union-tuples.scala +++ b/tests/pos/i14587.hard-union-tuples.scala @@ -3,8 +3,9 @@ class Test: type Foo = Option[String] | Option[Int] def test(foo: Foo) = - val (_, foo2: Foo) = // was: the type test for Test.this.Foo cannot be checked at runtime + val (_, foo2: Foo) = ( // was: the type test for Test.this.Foo cannot be checked at runtime foo match case Some(s: String) => ((), s) case _ => ((), 0) + ): @unchecked foo2 diff --git a/tests/semanticdb/expect/Synthetic.expect.scala b/tests/semanticdb/expect/Synthetic.expect.scala index 2672b8106785..a4419aa8bd82 100644 --- a/tests/semanticdb/expect/Synthetic.expect.scala +++ b/tests/semanticdb/expect/Synthetic.expect.scala @@ -9,11 +9,11 @@ class Synthetic/*<-example::Synthetic#*/ { // See https://github.com/scalameta/scalameta/issues/977 val Name/*<-example::Synthetic#Name.*/ = "name:(.*)".r/*->scala::collection::StringOps#r().*/ - val x/*<-example::Synthetic#x.*/ #::/*->scala::package.`#::`.*/ xs/*<-example::Synthetic#xs.*/ = LazyList/*->scala::package.LazyList.*/(1, 2) - val Name/*->example::Synthetic#Name.*/(name/*<-example::Synthetic#name.*/) = "name:foo" + val x/*<-example::Synthetic#x.*/ #::/*->scala::package.`#::`.*/ xs/*<-example::Synthetic#xs.*/ = LazyList/*->scala::package.LazyList.*/(1, 2): @unchecked + val Name/*->example::Synthetic#Name.*/(name/*<-example::Synthetic#name.*/) = "name:foo": @unchecked 1 #:: 2 #:: LazyList/*->scala::package.LazyList.*/.empty/*->scala::collection::immutable::LazyList.empty().*/ - val a1/*<-example::Synthetic#a1.*/ #::/*->scala::package.`#::`.*/ a2/*<-example::Synthetic#a2.*/ #::/*->scala::package.`#::`.*/ as/*<-example::Synthetic#as.*/ = LazyList/*->scala::package.LazyList.*/(1, 2) + val a1/*<-example::Synthetic#a1.*/ #::/*->scala::package.`#::`.*/ a2/*<-example::Synthetic#a2.*/ #::/*->scala::package.`#::`.*/ as/*<-example::Synthetic#as.*/ = LazyList/*->scala::package.LazyList.*/(1, 2): @unchecked val lst/*<-example::Synthetic#lst.*/ = 1 #:: 2 #:: LazyList/*->scala::package.LazyList.*/.empty/*->scala::collection::immutable::LazyList.empty().*/ diff --git a/tests/semanticdb/expect/Synthetic.scala b/tests/semanticdb/expect/Synthetic.scala index 10d13e936468..71fb5fdf70a3 100644 --- a/tests/semanticdb/expect/Synthetic.scala +++ b/tests/semanticdb/expect/Synthetic.scala @@ -9,11 +9,11 @@ class Synthetic { // See https://github.com/scalameta/scalameta/issues/977 val Name = "name:(.*)".r - val x #:: xs = LazyList(1, 2) - val Name(name) = "name:foo" + val x #:: xs = LazyList(1, 2): @unchecked + val Name(name) = "name:foo": @unchecked 1 #:: 2 #:: LazyList.empty - val a1 #:: a2 #:: as = LazyList(1, 2) + val a1 #:: a2 #:: as = LazyList(1, 2): @unchecked val lst = 1 #:: 2 #:: LazyList.empty From 5d2f10ed2e6f75502acd78505aca7f1876cfb266 Mon Sep 17 00:00:00 2001 From: Tom Grigg Date: Tue, 18 Jan 2022 15:33:01 -0800 Subject: [PATCH 09/12] Fix tests crashing under strict pattern binding warnings Before this commit, the tests listed below would crash when the stricter pattern binding rules were enforced (whether using `-source future` or now enabled by default) - neg/parser-stability-14.scala - neg/i4453.scala - fuzzy/CCE-aafcaa9cd2611d22f63273738d637f5bec6e7152.scala - fuzzy/comment3.scala with a common stack trace: dotty.tools.dotc.core.Types$PreviousErrorType cannot be cast to dotty.tools.dotc.core.Types$TermRef dotty.tools.dotc.transform.patmat.SpaceEngine$.isIrrefutable(Space.scala:316) dotty.tools.dotc.typer.Checking.recur$1(Checking.scala:828) dotty.tools.dotc.typer.Checking.checkIrrefutable(Checking.scala:843) dotty.tools.dotc.typer.Checking.checkIrrefutable$(Checking.scala:775) dotty.tools.dotc.typer.Typer.checkIrrefutable(Typer.scala:119) ... --- compiler/src/dotty/tools/dotc/transform/patmat/Space.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala index 56a595780365..008198526999 100644 --- a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala +++ b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala @@ -312,9 +312,9 @@ object SpaceEngine { * @param unapp The unapply function tree */ def isIrrefutable(unapp: tpd.Tree, argLen: Int)(using Context): Boolean = { - val fun1 = tpd.funPart(unapp) - val funRef = fun1.tpe.asInstanceOf[TermRef] - isIrrefutable(funRef, argLen) + tpd.funPart(unapp).tpe match + case funRef: TermRef => isIrrefutable(funRef, argLen) + case _: ErrorType => false } } From c5c1d60da047a24d25b4e15cbd50c47517dd608a Mon Sep 17 00:00:00 2001 From: Tom Grigg Date: Wed, 19 Jan 2022 09:39:20 -0800 Subject: [PATCH 10/12] Adapt community build for strict pattern binding warnings --- community-build/community-projects/akka | 2 +- community-build/community-projects/cats | 2 +- community-build/community-projects/shapeless | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/community-build/community-projects/akka b/community-build/community-projects/akka index ca4fedeefe9b..ed97fe5233cb 160000 --- a/community-build/community-projects/akka +++ b/community-build/community-projects/akka @@ -1 +1 @@ -Subproject commit ca4fedeefe9bf98d76d34b65d0479ea8257931aa +Subproject commit ed97fe5233cbda2da02abad50d48c310077b313c diff --git a/community-build/community-projects/cats b/community-build/community-projects/cats index 6bbbc1e3477b..704c7fd5d207 160000 --- a/community-build/community-projects/cats +++ b/community-build/community-projects/cats @@ -1 +1 @@ -Subproject commit 6bbbc1e3477b7da6b58a97844f773c3c445b4e5e +Subproject commit 704c7fd5d2079854637885514fccb62165e267f7 diff --git a/community-build/community-projects/shapeless b/community-build/community-projects/shapeless index e58dd710b5c4..04e8cebc6097 160000 --- a/community-build/community-projects/shapeless +++ b/community-build/community-projects/shapeless @@ -1 +1 @@ -Subproject commit e58dd710b5c46d54336242a7ba4bab90d440d4f8 +Subproject commit 04e8cebc6097357598b15caf428e86b78dde0888 From dc5d1d741daa86607c1421be20bb3c127a6657e1 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Mon, 16 May 2022 13:41:24 +0200 Subject: [PATCH 11/12] apply code review suggestions --- .../src/dotty/tools/dotc/config/Feature.scala | 2 +- .../dotty/tools/dotc/config/SourceVersion.scala | 4 ++++ compiler/src/dotty/tools/dotc/typer/Typer.scala | 5 ++++- .../language-versions/source-compatibility.md | 15 +++++++++------ 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/config/Feature.scala b/compiler/src/dotty/tools/dotc/config/Feature.scala index 868de1f71d76..4a87f5b4a537 100644 --- a/compiler/src/dotty/tools/dotc/config/Feature.scala +++ b/compiler/src/dotty/tools/dotc/config/Feature.scala @@ -90,7 +90,7 @@ object Feature: */ def warnOnMigration(msg: Message, pos: SrcPos, version: SourceVersion)(using Context): Boolean = if sourceVersion.isMigrating && sourceVersion.stable == version - || (version == `3.0` || version == `3.1` || version == `3.2`) && migrateTo3 + || (version == `3.0` || version == `3.1`) && migrateTo3 then report.migrationWarning(msg, pos) true diff --git a/compiler/src/dotty/tools/dotc/config/SourceVersion.scala b/compiler/src/dotty/tools/dotc/config/SourceVersion.scala index 545e2f2d9b42..56d5fb464e95 100644 --- a/compiler/src/dotty/tools/dotc/config/SourceVersion.scala +++ b/compiler/src/dotty/tools/dotc/config/SourceVersion.scala @@ -17,6 +17,10 @@ enum SourceVersion: def isAtLeast(v: SourceVersion) = stable.ordinal >= v.ordinal + def isBetween(low: SourceVersion, high: SourceVersion): Boolean = + require(low.ordinal < high.ordinal) + isAtLeast(low) && stable.ordinal <= high.ordinal + object SourceVersion extends Property.Key[SourceVersion]: def defaultSourceVersion = `3.2` diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 9cfae53dace9..4863dc681da5 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1619,7 +1619,10 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer tree.selector.removeAttachment(desugar.CheckIrrefutable) match { case Some(checkMode) if !sel.tpe.hasAnnotation(defn.UncheckedAnnot) => val isPatDef = checkMode == desugar.MatchCheck.IrrefutablePatDef - if !checkIrrefutable(sel, pat, isPatDef) && sourceVersion.isAtLeast(`3.2`) && sourceVersion.isMigrating then + if !checkIrrefutable(sel, pat, isPatDef) + && sourceVersion.isMigrating + && sourceVersion.isBetween(`3.2`, `future`) + then if isPatDef then uncheckedBrackets(tree.selector) match case None => patch(Span(tree.selector.span.end), ": @unchecked") diff --git a/docs/_docs/reference/language-versions/source-compatibility.md b/docs/_docs/reference/language-versions/source-compatibility.md index 029a3674ba73..2b10d4ee5269 100644 --- a/docs/_docs/reference/language-versions/source-compatibility.md +++ b/docs/_docs/reference/language-versions/source-compatibility.md @@ -6,20 +6,23 @@ movedTo: https://docs.scala-lang.org/scala3/reference/language-versions.html Scala 3 does NOT guarantee source compatibility between different minor language versions (e.g. some syntax valid in 3.x might get deprecated and then phased out in 3.y for y > x). There are also some syntax structures that were valid in Scala 2 but are not anymore in Scala 3. However the compiler provides a possibility to specify the desired version of syntax used in a particular file or globally for a run of the compiler to make migration between versions easier. -The default Scala language syntax version currently supported by the Dotty compiler is [`3.0`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$3/0$.html). There are also other language versions that can be specified instead: +The default Scala language syntax version currently supported by the Dotty compiler is [`3.2`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$3/2$.html). There are also other language versions that can be specified instead: -- [`3.0-migration`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$3/0-migration$.html): Same as `3.0` but with a Scala 2 compatibility mode that helps moving Scala 2.13 sources over to Scala 3. In particular, it +- [`3.0-migration`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$3/0-migration$.html): Same as +`3.0` and `3.1`, but with a Scala 2 compatibility mode that helps moving Scala 2.13 sources over to Scala 3. In particular, it - flags some Scala 2 constructs that are disallowed in Scala 3 as migration warnings instead of hard errors, - changes some rules to be more lenient and backwards compatible with Scala 2.13 - gives some additional warnings where the semantics has changed between Scala 2.13 and 3.0 - in conjunction with `-rewrite`, offer code rewrites from Scala 2.13 to 3.0. -- [`future`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$future$.html): A preview of changes introduced in the next versions after 3.0. In the doc pages here we refer to the language version with these changes as `3.1`, but it might be that some of these changes will be rolled out in later `3.x` versions. +- [`3.0`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$3/0$.html), [`3.1`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$3/1$.html): the default set of features included in scala versions `3.0.0` to `3.1.3`. +- [`3.2`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$3/2$.html): the same as `3.0` and `3.1`, but [stricter pattern bindings](https://docs.scala-lang.org/scala3/reference/changed-features/pattern-bindings.html) are now enabled (part of `future` in earlier `3.x` releases), producing warnings for refutable patterns. These warnings can be silenced to achieve the same runtime behavior, but in `future` they become errors and refutable patterns will not compile. +- [`3.2-migration`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$3/2-migration$.html): the same as `3.2`, but in conjunction with `-rewrite`, offer code rewrites from Scala `3.0/3.1` to `3.2`. +- [`future`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$future$.html): A preview of changes that will be introduced in `3.x` versions after `3.2`. +Some Scala 2 specific idioms are dropped in this version. The feature set supported by this version may grow over time as features become stabilised for preview. -Some Scala 2 specific idioms will be dropped in this version. The feature set supported by this version will be refined over time as we approach its release. - -- [`future-migration`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$future-migration$.html): Same as `future` but with additional helpers to migrate from `3.0`. Similarly to the helpers available under `3.0-migration`, these include migration warnings and optional rewrites. +- [`future-migration`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$future-migration$.html): Same as `future` but with additional helpers to migrate from `3.2`. Similarly to the helpers available under `3.0-migration`, these include migration warnings and optional rewrites. There are two ways to specify a language version : From e29c40fb7eb5e23607632f804c8314a4c4a1de27 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Tue, 17 May 2022 14:05:32 +0200 Subject: [PATCH 12/12] revert add isBetween --- compiler/src/dotty/tools/dotc/config/SourceVersion.scala | 4 ---- compiler/src/dotty/tools/dotc/typer/Typer.scala | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/config/SourceVersion.scala b/compiler/src/dotty/tools/dotc/config/SourceVersion.scala index 56d5fb464e95..545e2f2d9b42 100644 --- a/compiler/src/dotty/tools/dotc/config/SourceVersion.scala +++ b/compiler/src/dotty/tools/dotc/config/SourceVersion.scala @@ -17,10 +17,6 @@ enum SourceVersion: def isAtLeast(v: SourceVersion) = stable.ordinal >= v.ordinal - def isBetween(low: SourceVersion, high: SourceVersion): Boolean = - require(low.ordinal < high.ordinal) - isAtLeast(low) && stable.ordinal <= high.ordinal - object SourceVersion extends Property.Key[SourceVersion]: def defaultSourceVersion = `3.2` diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 4863dc681da5..5e10546ca128 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1620,8 +1620,8 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer case Some(checkMode) if !sel.tpe.hasAnnotation(defn.UncheckedAnnot) => val isPatDef = checkMode == desugar.MatchCheck.IrrefutablePatDef if !checkIrrefutable(sel, pat, isPatDef) + && sourceVersion.isAtLeast(`3.2`) && sourceVersion.isMigrating - && sourceVersion.isBetween(`3.2`, `future`) then if isPatDef then uncheckedBrackets(tree.selector) match case None =>