diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 955597261327..437a34a53902 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala @@ -169,7 +169,7 @@ trait BCodeSkelBuilder extends BCodeHelpers { /* ---------------- helper utils for generating classes and fields ---------------- */ - def genPlainClass(cd0: TypeDef) = cd0 match { + def genPlainClass(cd0: TypeDef) = (cd0: @unchecked) match { case TypeDef(_, impl: Template) => assert(cnode == null, "GenBCode detected nested methods.") diff --git a/compiler/src/dotty/tools/dotc/core/Comments.scala b/compiler/src/dotty/tools/dotc/core/Comments.scala index 92160c97973d..b1d1e387c2cf 100644 --- a/compiler/src/dotty/tools/dotc/core/Comments.scala +++ b/compiler/src/dotty/tools/dotc/core/Comments.scala @@ -405,15 +405,10 @@ object Comments { val Trim = "(?s)^[\\s&&[^\n\r]]*(.*?)\\s*$".r val raw = ctx.docCtx.flatMap(_.docstring(sym).map(_.raw)).getOrElse("") - defs(sym) ++= defines(raw).map { - str => { - val start = skipWhitespace(str, "@define".length) - val (key, value) = str.splitAt(skipVariable(str, start)) - key.drop(start) -> value - } - } map { - case (key, Trim(value)) => - variableName(key) -> value.replaceAll("\\s+\\*+$", "") + defs(sym) ++= defines(raw).map { str => + val start = skipWhitespace(str, "@define".length) + val (key, Trim(value)) = str.splitAt(skipVariable(str, start)): @unchecked + variableName(key.drop(start)) -> value.replaceAll("\\s+\\*+$", "") } } diff --git a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala index 8f015bcd5f42..20b6a2e5b272 100644 --- a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala +++ b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala @@ -813,7 +813,6 @@ object SpaceEngine { } private def exhaustivityCheckable(sel: Tree)(using Context): Boolean = { - val seen = collection.mutable.Set.empty[Symbol] // Possible to check everything, but be compatible with scalac by default def isCheckable(tp: Type): Boolean = @@ -828,10 +827,7 @@ object SpaceEngine { }) || tpw.isRef(defn.BooleanClass) || classSym.isAllOf(JavaEnumTrait) || - classSym.is(Case) && { - if seen.add(classSym) then productSelectorTypes(tpw, sel.srcPos).exists(isCheckable(_)) - else true // recursive case class: return true and other members can still fail the check - } + classSym.is(Case) !sel.tpe.hasAnnotation(defn.UncheckedAnnot) && { diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 69237c2aa493..a1a01823e2f3 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -1290,29 +1290,30 @@ trait Implicits: if alt1.isExtension then // Fall back: if both results are extension method applications, // compare the extension methods instead of their wrappers. - def stripExtension(alt: SearchSuccess) = methPart(stripApply(alt.tree)).tpe - (stripExtension(alt1), stripExtension(alt2)) match - case (ref1: TermRef, ref2: TermRef) => - // ref1 and ref2 might refer to type variables owned by - // alt1.tstate and alt2.tstate respectively, to compare the - // alternatives correctly we need a TyperState that includes - // constraints from both sides, see - // tests/*/extension-specificity2.scala for test cases. - val constraintsIn1 = alt1.tstate.constraint ne ctx.typerState.constraint - val constraintsIn2 = alt2.tstate.constraint ne ctx.typerState.constraint - def exploreState(alt: SearchSuccess): TyperState = - alt.tstate.fresh(committable = false) - val comparisonState = - if constraintsIn1 && constraintsIn2 then - exploreState(alt1).mergeConstraintWith(alt2.tstate) - else if constraintsIn1 then - exploreState(alt1) - else if constraintsIn2 then - exploreState(alt2) - else - ctx.typerState - - diff = inContext(ctx.withTyperState(comparisonState)): + def stripExtension(alt: SearchSuccess) = + methPart(stripApply(alt.tree)).tpe: @unchecked match { case ref: TermRef => ref } + val ref1 = stripExtension(alt1) + val ref2 = stripExtension(alt2) + // ref1 and ref2 might refer to type variables owned by + // alt1.tstate and alt2.tstate respectively, to compare the + // alternatives correctly we need a TyperState that includes + // constraints from both sides, see + // tests/*/extension-specificity2.scala for test cases. + val constraintsIn1 = alt1.tstate.constraint ne ctx.typerState.constraint + val constraintsIn2 = alt2.tstate.constraint ne ctx.typerState.constraint + def exploreState(alt: SearchSuccess): TyperState = + alt.tstate.fresh(committable = false) + val comparisonState = + if constraintsIn1 && constraintsIn2 then + exploreState(alt1).mergeConstraintWith(alt2.tstate) + else if constraintsIn1 then + exploreState(alt1) + else if constraintsIn2 then + exploreState(alt2) + else + ctx.typerState + + diff = inContext(ctx.withTyperState(comparisonState)): compare(ref1, ref2) else // alt1 is a conversion, prefer extension alt2 over it diff = -1 diff --git a/compiler/test/dotty/tools/scripting/BashExitCodeTests.scala b/compiler/test/dotty/tools/scripting/BashExitCodeTests.scala index f2e64b5fad62..3aad9ef8813f 100644 --- a/compiler/test/dotty/tools/scripting/BashExitCodeTests.scala +++ b/compiler/test/dotty/tools/scripting/BashExitCodeTests.scala @@ -62,6 +62,9 @@ class BashExitCodeTests: @Test def xPluginList = scala("-Xplugin-list")(0) @Test def vPhases = scala("-Vphases")(0) + @Test def replEval = + scala("--repl-quit-after-init", "--repl-init-script", "'val i = 2 * 2; val j = i + 2'")(0) + /** A utility for running two commands in a row, like you do in bash. */ extension (inline u1: Unit) inline def & (inline u2: Unit): Unit = { u1; u2 } end BashExitCodeTests diff --git a/library/src/scala/annotation/newMain.scala b/library/src/scala/annotation/newMain.scala index 552e4225a648..686f3bf14b54 100644 --- a/library/src/scala/annotation/newMain.scala +++ b/library/src/scala/annotation/newMain.scala @@ -253,6 +253,7 @@ final class newMain extends MainAnnotation[FromString, Any]: case (arg +: t, "") => recurse(t, arg, acc) case (arg +: t, l) if l.length + 1 + arg.length <= maxLength => recurse(t, s"$l $arg", acc) case (arg +: t, l) => recurse(t, arg, acc :+ l) + case (_, _) => acc } recurse(argsUsage, "", Vector()).toList diff --git a/scaladoc/src/dotty/tools/scaladoc/site/templates.scala b/scaladoc/src/dotty/tools/scaladoc/site/templates.scala index 92e0096e5af1..56a0f7f6d6b6 100644 --- a/scaladoc/src/dotty/tools/scaladoc/site/templates.scala +++ b/scaladoc/src/dotty/tools/scaladoc/site/templates.scala @@ -102,11 +102,9 @@ case class TemplateFile( ctx.layouts.getOrElse(name, throw new RuntimeException(s"No layouts named $name in ${ctx.layouts}")) ) - def asJavaElement(o: Object): Object = o match - case m: Map[_, _] => m.transform { - case (k: String, v: Object) => asJavaElement(v) - }.asJava - case l: List[_] => l.map(x => asJavaElement(x.asInstanceOf[Object])).asJava + def asJavaElement(o: Any): Any = o match + case m: Map[?, ?] => m.transform { (k, v) => asJavaElement(v) }.asJava + case l: List[?] => l.map(asJavaElement).asJava case other => other // Library requires mutable maps.. diff --git a/tests/pos/switches.scala b/tests/pos/switches.scala index bd7e44f1c8cf..beb378debb40 100644 --- a/tests/pos/switches.scala +++ b/tests/pos/switches.scala @@ -42,6 +42,7 @@ class Test { case IntAnyVal(100) => 2 case IntAnyVal(1000) => 3 case IntAnyVal(10000) => 4 + case _ => -1 } } diff --git a/tests/warn/i15662.scala b/tests/warn/i15662.scala index 0cf0e57ed0c3..f17a040b4980 100644 --- a/tests/warn/i15662.scala +++ b/tests/warn/i15662.scala @@ -5,6 +5,7 @@ case class Composite[T](v: T) def m(composite: Composite[?]): Unit = composite match { case Composite[Int](v) => println(v) // warn: cannot be checked at runtime + case _ => println("OTHER") } def m2(composite: Composite[?]): Unit = diff --git a/tests/warn/i21218.scala b/tests/warn/i21218.scala index 29fa957e2e70..db0810c5d7b0 100644 --- a/tests/warn/i21218.scala +++ b/tests/warn/i21218.scala @@ -6,5 +6,6 @@ def Test[U, A](thisElem: A, thatElem: U) = { case (`passedEnd`, r: U @unchecked) => (thisElem, r) case (l: A @unchecked, `passedEnd`) => (l, thatElem) case t: (A, U) @unchecked => t // false-positive warning + case (t1, t2) => (t1, t2) } } diff --git a/tests/warn/i21525.scala b/tests/warn/i21525.scala index 721486c4bd64..7fecb14a9673 100644 --- a/tests/warn/i21525.scala +++ b/tests/warn/i21525.scala @@ -1,7 +1,6 @@ //> using options -Werror -Wunused:imports import scala.reflect.{Typeable, TypeTest} -import compiletime.* trait A { type B @@ -22,7 +21,7 @@ def f(a: A, b: a.B): Boolean = { trait T: type X - given Typeable[X] = deferred + given tpe: Typeable[X] def g(t: T, x: Any) = import t.X diff --git a/tests/warn/i22590.arity2.scala b/tests/warn/i22590.arity2.scala new file mode 100644 index 000000000000..8ce84ab299f1 --- /dev/null +++ b/tests/warn/i22590.arity2.scala @@ -0,0 +1,15 @@ +sealed trait T_B +case class CC_A() extends T_B +case class CC_C() extends T_B + +sealed trait T_A +case class CC_B[B](a: B,b:T_B) extends T_A + + +@main def test() = { + val v_a: CC_B[Int] = null + val v_b: Int = v_a match { // warn: match may not be exhaustive. + case CC_B(12, CC_A()) => 0 + case CC_B(_, CC_C()) => 0 + } +} diff --git a/tests/warn/i22590.scala b/tests/warn/i22590.scala new file mode 100644 index 000000000000..1520a07b86b8 --- /dev/null +++ b/tests/warn/i22590.scala @@ -0,0 +1,9 @@ +sealed trait T_A +case class CC_B[T](a: T) extends T_A + +@main def test() = { + val v_a: CC_B[Int] = CC_B(10) + val v_b: Int = v_a match{ // warn: match may not be exhaustive. + case CC_B(12) => 0 + } +} diff --git a/tests/warn/opaque-match.scala b/tests/warn/opaque-match.scala index 06cca835ab91..f66370def9b2 100644 --- a/tests/warn/opaque-match.scala +++ b/tests/warn/opaque-match.scala @@ -13,8 +13,10 @@ def Test[T] = case _: C => ??? // ok C() match case _: O.T => ??? // warn + case _ => ??? C() match case _: T => ??? // warn + case _ => ??? (??? : Any) match case _: List[O.T] => ??? // warn diff --git a/tests/pos/t10373.scala b/tests/warn/t10373.scala similarity index 74% rename from tests/pos/t10373.scala rename to tests/warn/t10373.scala index 0d91313f694d..ca49e7b1ce16 100644 --- a/tests/pos/t10373.scala +++ b/tests/warn/t10373.scala @@ -1,4 +1,4 @@ -//> using options -Xfatal-warnings -deprecation -feature +//> using options -deprecation -feature abstract class Foo { def bar(): Unit = this match { @@ -7,7 +7,7 @@ abstract class Foo { // Works fine } - def baz(that: Foo): Unit = (this, that) match { + def baz(that: Foo): Unit = (this, that) match { // warn: match may not be exhaustive. case (Foo_1(), _) => //do something case (Foo_2(), _) => //do something // match may not be exhaustive