diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala b/compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala index 437a34a53902..955597261327 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: @unchecked) match { + def genPlainClass(cd0: TypeDef) = cd0 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 b1d1e387c2cf..92160c97973d 100644 --- a/compiler/src/dotty/tools/dotc/core/Comments.scala +++ b/compiler/src/dotty/tools/dotc/core/Comments.scala @@ -405,10 +405,15 @@ 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, Trim(value)) = str.splitAt(skipVariable(str, start)): @unchecked - variableName(key.drop(start)) -> value.replaceAll("\\s+\\*+$", "") + 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+\\*+$", "") } } diff --git a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala index 0dfa73035099..def5eaec708e 100644 --- a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala +++ b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala @@ -801,6 +801,7 @@ 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 = @@ -815,7 +816,10 @@ object SpaceEngine { }) || tpw.isRef(defn.BooleanClass) || classSym.isAllOf(JavaEnumTrait) || - classSym.is(Case) + 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 + } !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 063513f1c295..50a7686c3db3 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -1294,30 +1294,29 @@ 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: @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)): + 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)): 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 3aad9ef8813f..f2e64b5fad62 100644 --- a/compiler/test/dotty/tools/scripting/BashExitCodeTests.scala +++ b/compiler/test/dotty/tools/scripting/BashExitCodeTests.scala @@ -62,9 +62,6 @@ 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 686f3bf14b54..552e4225a648 100644 --- a/library/src/scala/annotation/newMain.scala +++ b/library/src/scala/annotation/newMain.scala @@ -253,7 +253,6 @@ 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 56a0f7f6d6b6..92e0096e5af1 100644 --- a/scaladoc/src/dotty/tools/scaladoc/site/templates.scala +++ b/scaladoc/src/dotty/tools/scaladoc/site/templates.scala @@ -102,9 +102,11 @@ case class TemplateFile( ctx.layouts.getOrElse(name, throw new RuntimeException(s"No layouts named $name in ${ctx.layouts}")) ) - def asJavaElement(o: Any): Any = o match - case m: Map[?, ?] => m.transform { (k, v) => asJavaElement(v) }.asJava - case l: List[?] => l.map(asJavaElement).asJava + 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 case other => other // Library requires mutable maps.. diff --git a/tests/pos/switches.scala b/tests/pos/switches.scala index beb378debb40..bd7e44f1c8cf 100644 --- a/tests/pos/switches.scala +++ b/tests/pos/switches.scala @@ -42,7 +42,6 @@ class Test { case IntAnyVal(100) => 2 case IntAnyVal(1000) => 3 case IntAnyVal(10000) => 4 - case _ => -1 } } diff --git a/tests/warn/t10373.scala b/tests/pos/t10373.scala similarity index 74% rename from tests/warn/t10373.scala rename to tests/pos/t10373.scala index ca49e7b1ce16..0d91313f694d 100644 --- a/tests/warn/t10373.scala +++ b/tests/pos/t10373.scala @@ -1,4 +1,4 @@ -//> using options -deprecation -feature +//> using options -Xfatal-warnings -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 { // warn: match may not be exhaustive. + def baz(that: Foo): Unit = (this, that) match { case (Foo_1(), _) => //do something case (Foo_2(), _) => //do something // match may not be exhaustive diff --git a/tests/warn/i15662.scala b/tests/warn/i15662.scala index f17a040b4980..0cf0e57ed0c3 100644 --- a/tests/warn/i15662.scala +++ b/tests/warn/i15662.scala @@ -5,7 +5,6 @@ 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 db0810c5d7b0..29fa957e2e70 100644 --- a/tests/warn/i21218.scala +++ b/tests/warn/i21218.scala @@ -6,6 +6,5 @@ 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/i22590.arity2.scala b/tests/warn/i22590.arity2.scala deleted file mode 100644 index 8ce84ab299f1..000000000000 --- a/tests/warn/i22590.arity2.scala +++ /dev/null @@ -1,15 +0,0 @@ -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 deleted file mode 100644 index 1520a07b86b8..000000000000 --- a/tests/warn/i22590.scala +++ /dev/null @@ -1,9 +0,0 @@ -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 f66370def9b2..06cca835ab91 100644 --- a/tests/warn/opaque-match.scala +++ b/tests/warn/opaque-match.scala @@ -13,10 +13,8 @@ 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