From 840f6a3958b917edac3d26597b463253dd8f6f4a Mon Sep 17 00:00:00 2001 From: Wojciech Mazur Date: Wed, 26 Jun 2024 18:07:51 +0200 Subject: [PATCH] Space: Replace showType & make Space Showable Replace showType with a small tweak to RefinedPrinter, so the rest of the logic is followed. For instance, show infix types and tuples correctly. Also, make Space Showable, reusing the existing logic for Space, but additionally specifying the Space class name, which is important for following Space traces. [Cherry-picked edc74b717046bb1360c85f9c94ceb1bc35eade22][modified] --- .../tools/dotc/transform/patmat/Space.scala | 232 +++++++----------- .../transform/patmat/SpaceEngineTest.scala | 27 +- tests/patmat/aliasing.check | 6 +- tests/patmat/i12020.check | 2 +- tests/patmat/i2502.check | 2 +- tests/patmat/i2502b.check | 2 +- tests/patmat/i3938.check | 2 +- tests/patmat/i6255b.check | 2 +- tests/patmat/t10100.check | 2 +- tests/patmat/t9779.check | 2 +- 10 files changed, 106 insertions(+), 173 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala index 5280b63b20d3..16c46d47c0c3 100644 --- a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala +++ b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala @@ -3,23 +3,13 @@ package dotc package transform package patmat -import core.* -import Types.* -import Contexts.* -import Flags.* -import ast.* -import Decorators.{ show => _, * } -import Symbols.* -import StdNames.* -import NameOps.* -import Constants.* -import typer.* -import Applications.* -import Inferencing.* -import ProtoTypes.* +import core.*, Constants.*, Contexts.*, Decorators.*, Flags.*, Names.*, NameOps.*, StdNames.*, Symbols.*, Types.* +import ast.*, tpd.* +import config.Printers.* +import printing.{ Printer, * }, Texts.* import reporting.* -import config.Printers.{exhaustivity => debug} -import util.{SrcPos, NoSourcePosition} +import typer.*, Applications.*, Inferencing.*, ProtoTypes.* +import util.* import scala.annotation.internal.sharable import scala.collection.mutable @@ -56,7 +46,7 @@ import SpaceEngine.* */ /** space definition */ -sealed trait Space: +sealed trait Space extends Showable: @sharable private val isSubspaceCache = mutable.HashMap.empty[Space, Boolean] @@ -67,9 +57,7 @@ sealed trait Space: if (a ne a2) || (b ne b2) then a2.isSubspace(b2) else if a == Empty then true else if b == Empty then false - else trace(s"isSubspace(${show(this)}, ${show(b)})", debug) { - isSubspaceCache.getOrElseUpdate(b, computeIsSubspace(a, b)) - } + else isSubspaceCache.getOrElseUpdate(b, computeIsSubspace(a, b)) @sharable private var mySimplified: Space | Null = null @@ -80,6 +68,13 @@ sealed trait Space: mySimplified = simplified simplified else simplified + + def toText(p: Printer): Text = inContext(p.printerContext)(this match { + case Empty => s"Empty" + case sp: Typ => s"Typ(${display(sp)})" + case sp: Prod => s"Prod(${display(sp)})" + case sp: Or => s"Or(${display(sp)})" + }) end Space /** Empty space */ @@ -114,15 +109,13 @@ case class Prod(tp: Type, unappTp: TermRef, params: List[Space]) extends Space case class Or(spaces: Seq[Space]) extends Space object SpaceEngine { - import tpd.* - def simplify(space: Space)(using Context): Space = space.simplify def isSubspace(a: Space, b: Space)(using Context): Boolean = a.isSubspace(b) def canDecompose(typ: Typ)(using Context): Boolean = typ.canDecompose def decompose(typ: Typ)(using Context): List[Typ] = typ.decompose /** Simplify space such that a space equal to `Empty` becomes `Empty` */ - def computeSimplify(space: Space)(using Context): Space = trace(s"simplify ${show(space)} --> ", debug, show)(space match { + def computeSimplify(space: Space)(using Context): Space = trace(s"simplify($space)")(space match { case Prod(tp, fun, spaces) => val sps = spaces.mapconserve(simplify) if sps.contains(Empty) then Empty @@ -173,7 +166,7 @@ object SpaceEngine { } /** Is `a` a subspace of `b`? Equivalent to `simplify(simplify(a) - simplify(b)) == Empty`, but faster */ - def computeIsSubspace(a: Space, b: Space)(using Context): Boolean = { + def computeIsSubspace(a: Space, b: Space)(using Context): Boolean = trace(s"isSubspace($a, $b)") { val a2 = simplify(a) val b2 = simplify(b) if (a ne a2) || (b ne b2) then isSubspace(a2, b2) @@ -201,7 +194,7 @@ object SpaceEngine { } /** Intersection of two spaces */ - def intersect(a: Space, b: Space)(using Context): Space = trace(s"${show(a)} & ${show(b)}", debug, show) { + def intersect(a: Space, b: Space)(using Context): Space = trace(s"$a & $b") { (a, b) match { case (Empty, _) | (_, Empty) => Empty case (_, Or(ss)) => Or(ss.map(intersect(a, _)).filter(_ ne Empty)) @@ -210,11 +203,11 @@ object SpaceEngine { if isSubType(tp1, tp2) then a else if isSubType(tp2, tp1) then b else intersectUnrelatedAtomicTypes(tp1, tp2)(a) - case (a @ Typ(tp1, _), Prod(tp2, fun, ss)) => + case (a @ Typ(tp1, _), b @ Prod(tp2, fun, ss)) => if isSubType(tp2, tp1) then b else if isSubType(tp1, tp2) then a // problematic corner case: inheriting a case class else intersectUnrelatedAtomicTypes(tp1, tp2)(b) - case (Prod(tp1, fun, ss), b @ Typ(tp2, _)) => + case (a @ Prod(tp1, fun, ss), b @ Typ(tp2, _)) => if isSubType(tp1, tp2) then a else if isSubType(tp2, tp1) then a // problematic corner case: inheriting a case class else intersectUnrelatedAtomicTypes(tp1, tp2)(a) @@ -226,7 +219,7 @@ object SpaceEngine { } /** The space of a not covered by b */ - def minus(a: Space, b: Space)(using Context): Space = trace(s"${show(a)} - ${show(b)}", debug, show) { + def minus(a: Space, b: Space)(using Context): Space = trace(s"$a - $b") { (a, b) match { case (Empty, _) => Empty case (_, Empty) => a @@ -290,8 +283,8 @@ object SpaceEngine { /** Is the unapply or unapplySeq irrefutable? * @param unapp The unapply function tree */ - def isIrrefutable(unapp: tpd.Tree, argLen: Int)(using Context): Boolean = { - tpd.funPart(unapp).tpe match + def isIrrefutable(unapp: Tree, argLen: Int)(using Context): Boolean = { + funPart(unapp).tpe match case funRef: TermRef => isIrrefutable(funRef, argLen) case _: ErrorType => false } @@ -322,24 +315,24 @@ object SpaceEngine { * The types should be atomic (non-decomposable) and unrelated (neither * should be a subtype of the other). */ - def intersectUnrelatedAtomicTypes(tp1: Type, tp2: Type)(sp: Space)(using Context): Space = trace(i"atomic intersection: ${AndType(tp1, tp2)}", debug, show) { + def intersectUnrelatedAtomicTypes(tp1: Type, tp2: Type)(sp: Typ | Prod)(using Context): Space = trace(i"intersectUnrelatedAtomicTypes($tp1, $tp2)(${sp.className})") { // Precondition: !isSubType(tp1, tp2) && !isSubType(tp2, tp1). + def intersection = sp match + case sp: Prod => sp.copy(AndType(tp1, tp2)) + case sp: Typ => sp.copy(AndType(tp1, tp2)) if !ctx.mode.is(Mode.SafeNulls) && (tp1.isNullType || tp2.isNullType) then // Since projections of types don't include null, intersection with null is empty. Empty - else - val intersection = sp match - case sp: Prod => sp.copy(AndType(tp1, tp2)) - case _ => Typ(AndType(tp1, tp2), decomposed = false) + else if tp1.classSymbol.isNumericValueClass && tp2.classSymbol.isNumericValueClass then // unrelated numeric value classes can equal each other, so let's not consider type space intersection empty - if tp1.classSymbol.isNumericValueClass && tp2.classSymbol.isNumericValueClass then intersection - else if isPrimToBox(tp1, tp2) || isPrimToBox(tp2, tp1) then intersection - else if TypeComparer.provablyDisjoint(tp1, tp2) then Empty - else intersection + intersection + else if isPrimToBox(tp1, tp2) || isPrimToBox(tp2, tp1) then intersection + else if TypeComparer.provablyDisjoint(tp1, tp2) then Empty + else intersection } /** Return the space that represents the pattern `pat` */ - def project(pat: Tree)(using Context): Space = trace(i"project($pat ${pat.className} ${pat.tpe})", debug, show)(pat match { + def project(pat: Tree)(using Context): Space = trace(i"project($pat ${pat.className} ${pat.tpe})")(pat match { case Literal(c) => if (c.value.isInstanceOf[Symbol]) Typ(c.value.asInstanceOf[Symbol].termRef, decomposed = false) @@ -456,7 +449,10 @@ object SpaceEngine { * This is needed to avoid spurious unreachable warnings. See tests/patmat/i6197.scala. */ private def erase(tp: Type, inArray: Boolean = false, isValue: Boolean = false, isTyped: Boolean = false)(using Context): Type = - trace(i"erase($tp${if inArray then " inArray" else ""}${if isValue then " isValue" else ""}${if isTyped then " isTyped" else ""})", debug)(tp match { + val inArr = if inArray then " inArray" else "" + val isVal = if isValue then " isValue" else "" + val isTyp = if isTyped then " isTyped" else "" + trace(i"erase($tp ${tp.className}$inArr$isVal$isTyp)")(tp match { case tp @ AppliedType(tycon, args) if tycon.typeSymbol.isPatternBound => WildcardType @@ -505,7 +501,7 @@ object SpaceEngine { tp.isPrimitiveValueType && (defn.boxedType(tp).classSymbol eq pt.classSymbol) /** Is `tp1` a subtype of `tp2`? */ - def isSubType(tp1: Type, tp2: Type)(using Context): Boolean = trace(i"$tp1 <:< $tp2", debug, show = true) { + def isSubType(tp1: Type, tp2: Type)(using Context): Boolean = trace(i"$tp1 <:< $tp2") { if tp1 == ConstantType(Constant(null)) && !ctx.mode.is(Mode.SafeNulls) then tp2 == ConstantType(Constant(null)) else if tp1.isTupleXXLExtract(tp2) then true // See isTupleXXLExtract, fixes TupleXXL parameter type @@ -529,11 +525,9 @@ object SpaceEngine { /** Return term parameter types of the extractor `unapp`. * Parameter types of the case class type `tp`. Adapted from `unapplyPlan` in patternMatcher */ - def signature(unapp: TermRef, scrutineeTp: Type, argLen: Int)(using Context): List[Type] = { + def signature(unapp: TermRef, scrutineeTp: Type, argLen: Int)(using Context): List[Type] = trace(i"signature($unapp, $scrutineeTp, $argLen)") { val unappSym = unapp.symbol - // println("scrutineeTp = " + scrutineeTp.show) - val mt: MethodType = unapp.widen match { case mt: MethodType => mt case pt: PolyType => @@ -586,8 +580,6 @@ object SpaceEngine { } } - debug.println(s"signature of ${unappSym.showFullName} ----> ${sig.map(_.show).mkString(", ")}") - sig.map(_.annotatedToRepeated) } @@ -604,7 +596,7 @@ object SpaceEngine { } /** Decompose a type into subspaces -- assume the type can be decomposed */ - def decompose(tp: Type)(using Context): List[Type] = trace(i"decompose($tp)", debug) { + def decompose(tp: Type)(using Context): List[Type] = trace(i"decompose($tp)") { def rec(tp: Type, mixins: List[Type]): List[Type] = tp.dealias match case AndType(tp1, tp2) => var tpB = tp2 @@ -642,13 +634,11 @@ object SpaceEngine { else if (child.is(Private) || child.is(Sealed)) && child.isOneOf(AbstractOrTrait) then getChildren(child) else List(child) } - val children = getChildren(tp.classSymbol) - debug.println(i"candidates for $tp : $children") + val children = trace(i"getChildren($tp)")(getChildren(tp.classSymbol)) val parts = children.map { sym => val sym1 = if (sym.is(ModuleClass)) sym.sourceModule else sym - val refined = TypeOps.refineUsingParent(tp, sym1, mixins) - debug.println(i"$sym1 refined to $refined") + val refined = trace(i"refineUsingParent($tp, $sym1, $mixins)")(TypeOps.refineUsingParent(tp, sym1, mixins)) def inhabited(tp: Type): Boolean = tp.dealias match case AndType(tp1, tp2) => !TypeComparer.provablyDisjoint(tp1, tp2) @@ -660,7 +650,6 @@ object SpaceEngine { if inhabited(refined) then refined else NoType }.filter(_.exists) - debug.println(i"$tp decomposes to $parts") parts case _ => ListOfNoType @@ -695,49 +684,13 @@ object SpaceEngine { * * E.g. C.this.B --> B if current owner is C * C.this.x.T --> x.T if current owner is C - * X[T] --> X * C --> C if current owner is C !!! - * */ - def showType(tp: Type, showTypeArgs: Boolean = false)(using Context): String = { + private class LocalPrinter(_ctx: Context) extends RefinedPrinter(_ctx): val enclosingCls = ctx.owner.enclosingClass - - def isOmittable(sym: Symbol) = - sym.isEffectiveRoot || sym.isAnonymousClass || sym.name.isReplWrapperName || - ctx.definitions.unqualifiedOwnerTypes.exists(_.symbol == sym) || - sym.showFullName.startsWith("scala.") || - sym == enclosingCls || sym == enclosingCls.sourceModule - - def refinePrefix(tp: Type): String = tp match { - case NoPrefix => "" - case tp: NamedType if isOmittable(tp.symbol) => "" - case tp: ThisType => refinePrefix(tp.tref) - case tp: RefinedType => refinePrefix(tp.parent) - case tp: NamedType => tp.name.show.stripSuffix("$") - case tp: TypeVar => refinePrefix(tp.instanceOpt) - case _ => tp.show - } - - def refine(tp: Type): String = tp.stripped match { - case tp: RefinedType => refine(tp.parent) - case tp: AppliedType => - refine(tp.typeConstructor) + ( - if (showTypeArgs) tp.argInfos.map(refine).mkString("[", ",", "]") - else "" - ) - case tp: ThisType => refine(tp.tref) - case tp: NamedType => - val pre = refinePrefix(tp.prefix) - if (tp.name == tpnme.higherKinds) pre - else if (pre.isEmpty) tp.name.show.stripSuffix("$") - else pre + "." + tp.name.show.stripSuffix("$") - case tp: OrType => refine(tp.tp1) + " | " + refine(tp.tp2) - case _: TypeBounds => "_" - case _ => tp.show.stripSuffix("$") - } - - refine(tp) - } + override def isOmittablePrefix(sym: Symbol) = + super.isOmittablePrefix(sym) + || sym == enclosingCls || sym == enclosingCls.sourceModule /** Whether the counterexample is satisfiable. The space is flattened and non-empty. */ def satisfiable(sp: Space)(using Context): Boolean = { @@ -771,10 +724,8 @@ object SpaceEngine { checkConstraint(genConstraint(sp))(using ctx.fresh.setNewTyperState()) } - def showSpaces(ss: Seq[Space])(using Context): Seq[String] = ss.map(show) - - /** Display spaces */ - def show(s: Space)(using Context): String = { + /** Display spaces. Used for printing uncovered spaces in the in-exhaustive error message. */ + def display(s: Space)(using Context): String = inContext(ctx.fresh.setPrinterFn(LocalPrinter(_))) { def params(tp: Type): List[Type] = tp.classSymbol.primaryConstructor.info.firstParamTypes /** does the companion object of the given symbol have custom unapply */ @@ -791,39 +742,38 @@ object SpaceEngine { if (flattenList && tp <:< defn.NilType) "" else tp.symbol.showName case Typ(tp, decomposed) => - - val sym = tp.classSymbol - - if (ctx.definitions.isTupleNType(tp)) + val cls = tp.classSymbol + if ctx.definitions.isTupleNType(tp) then params(tp).map(_ => "_").mkString("(", ", ", ")") - else if (defn.ListType.isRef(sym)) - if (flattenList) "_*" else "_: List" - else if (defn.ConsType.isRef(sym)) - if (flattenList) "_, _*" else "List(_, _*)" - else if (tp.classSymbol.is(Sealed) && tp.classSymbol.hasAnonymousChild) - "_: " + showType(tp) + " (anonymous)" - else if (tp.classSymbol.is(CaseClass) && !hasCustomUnapply(tp.classSymbol)) - // use constructor syntax for case class - showType(tp) + params(tp).map(_ => "_").mkString("(", ", ", ")") - else if (decomposed) "_: " + showType(tp, showTypeArgs = true) - else "_" + else if defn.ListType.isRef(cls) then + if flattenList then "_*" else "_: List" + else if (defn.ConsType.isRef(cls)) + if flattenList then "_, _*" else "List(_, _*)" + else if cls.hasAnonymousChild then + s"_: ${tp.typeConstructor.show} (anonymous)" + else if cls.is(CaseClass) && !hasCustomUnapply(cls) then + // use constructor syntax for case class + tp.typeConstructor.show + params(tp).map(_ => "_").mkString("(", ", ", ")") + else if !decomposed then "_" + else "_: " + tp.show case Prod(tp, fun, params) => - if (ctx.definitions.isTupleNType(tp)) + if ctx.definitions.isTupleNType(tp) then "(" + params.map(doShow(_)).mkString(", ") + ")" - else if (tp.isRef(defn.ConsType.symbol)) - if (flattenList) params.map(doShow(_, flattenList)).filter(_.nonEmpty).mkString(", ") - else params.map(doShow(_, flattenList = true)).filter(!_.isEmpty).mkString("List(", ", ", ")") - else { - val sym = fun.symbol - val isUnapplySeq = sym.name.eq(nme.unapplySeq) + else if tp.isRef(defn.ConsType.symbol) then + val body = params.map(doShow(_, flattenList = true)).filter(_.nonEmpty).mkString(", ") + if flattenList then body else s"List($body)" + else + val isUnapplySeq = fun.symbol.name eq nme.unapplySeq val paramsStr = params.map(doShow(_, flattenList = isUnapplySeq)).mkString("(", ", ", ")") - showType(fun.prefix) + paramsStr - } + val prefix = fun.prefix match + case pre: TermRef => pre.symbol.typeRef + case pre => pre + prefix.typeConstructor.show + paramsStr case Or(ss) => ss.map(doShow(_, flattenList)).mkString(" | ") } - doShow(s, flattenList = false) + doShow(s) } private def exhaustivityCheckable(sel: Tree)(using Context): Boolean = { @@ -847,13 +797,11 @@ object SpaceEngine { else true // recursive case class: return true and other members can still fail the check } - val res = !sel.tpe.hasAnnotation(defn.UncheckedAnnot) && { + !sel.tpe.hasAnnotation(defn.UncheckedAnnot) + && { ctx.settings.YcheckAllPatmat.value || isCheckable(sel.tpe) } - - debug.println(s"exhaustivity checkable: ${sel.show} = $res") - res } /** Whether counter-examples should be further checked? True for GADTs. */ @@ -868,7 +816,7 @@ object SpaceEngine { /** Return the underlying type of non-module, non-constant, non-enum case singleton types. * Also widen ExprType to its result type, and rewrap any annotation wrappers. * For example, with `val opt = None`, widen `opt.type` to `None.type`. */ - def toUnderlying(tp: Type)(using Context): Type = trace(i"toUnderlying($tp)", show = true)(tp match { + def toUnderlying(tp: Type)(using Context): Type = trace(i"toUnderlying($tp)")(tp match { case _: ConstantType => tp case tp: TermRef if tp.symbol.is(Module) => tp case tp: TermRef if tp.symbol.isAllOf(EnumCase) => tp @@ -878,27 +826,25 @@ object SpaceEngine { case _ => tp }) - def checkExhaustivity(m: Match)(using Context): Unit = trace(i"checkExhaustivity($m)", debug) { + def checkExhaustivity(m: Match)(using Context): Unit = trace(i"checkExhaustivity($m)") { val selTyp = toUnderlying(m.selector.tpe).dealias - debug.println(i"selTyp = $selTyp") + val targetSpace = trace(i"targetSpace($selTyp)")(project(selTyp)) val patternSpace = Or(m.cases.foldLeft(List.empty[Space]) { (acc, x) => - val space = if (x.guard.isEmpty) project(x.pat) else Empty - debug.println(s"${x.pat.show} ====> ${show(space)}") + val space = if x.guard.isEmpty then trace(i"project(${x.pat})")(project(x.pat)) else Empty space :: acc }) val checkGADTSAT = shouldCheckExamples(selTyp) val uncovered = - flatten(simplify(minus(project(selTyp), patternSpace))).filter({ s => + flatten(simplify(minus(targetSpace, patternSpace))).filter({ s => s != Empty && (!checkGADTSAT || satisfiable(s)) }) - if uncovered.nonEmpty then val deduped = dedup(uncovered) - report.warning(PatternMatchExhaustivity(showSpaces(deduped), m), m.selector) + report.warning(PatternMatchExhaustivity(deduped.map(display), m), m.selector) } private def reachabilityCheckable(sel: Tree)(using Context): Boolean = @@ -911,17 +857,16 @@ object SpaceEngine { && !sel.tpe.widen.isRef(defn.QuotedExprClass) && !sel.tpe.widen.isRef(defn.QuotedTypeClass) - def checkReachability(m: Match)(using Context): Unit = trace(i"checkReachability($m)", debug) { + def checkReachability(m: Match)(using Context): Unit = trace(i"checkReachability($m)") { val cases = m.cases.toIndexedSeq val selTyp = toUnderlying(m.selector.tpe).dealias - debug.println(i"selTyp = $selTyp") val isNullable = selTyp.classSymbol.isNullableClass - val targetSpace = if isNullable + val targetSpace = trace(i"targetSpace($selTyp)")(if isNullable then project(OrType(selTyp, ConstantType(Constant(null)), soft = false)) else project(selTyp) - debug.println(s"targetSpace: ${show(targetSpace)}") + ) var i = 0 val len = cases.length @@ -931,16 +876,11 @@ object SpaceEngine { while (i < len) { val CaseDef(pat, guard, _) = cases(i) - debug.println(i"case pattern: $pat") - - val curr = project(pat) - debug.println(i"reachable? ${show(curr)}") + val curr = trace(i"project($pat)")(project(pat)) - val prev = simplify(Or(prevs)) - debug.println(s"prev: ${show(prev)}") + val covered = trace("covered")(simplify(intersect(curr, targetSpace))) - val covered = simplify(intersect(curr, targetSpace)) - debug.println(s"covered: ${show(covered)}") + val prev = trace("prev")(simplify(Or(prevs))) if prev == Empty && covered == Empty then // defer until a case is reachable deferred ::= pat diff --git a/compiler/test/dotty/tools/dotc/transform/patmat/SpaceEngineTest.scala b/compiler/test/dotty/tools/dotc/transform/patmat/SpaceEngineTest.scala index c13ef0532348..d7b2fd6a5173 100644 --- a/compiler/test/dotty/tools/dotc/transform/patmat/SpaceEngineTest.scala +++ b/compiler/test/dotty/tools/dotc/transform/patmat/SpaceEngineTest.scala @@ -27,12 +27,12 @@ class SpaceEngineTest: val a = Prod(tp, unappTp, params) val b = Empty - val res1 = isSubspace(a, b) + val res1 = a.isSubspace(b) - val a2 = simplify(a) - val b2 = simplify(b) + val a2 = a.simplify + val b2 = b.simplify val rem1 = minus(a2, b2) - val rem2 = simplify(rem1) + val rem2 = rem1.simplify val res2 = rem2 == Empty assertEquals( @@ -46,19 +46,12 @@ class SpaceEngineTest: |simplify(rem1) == Empty |rem2 == Empty | - |a = ${show(a)} - |b = ${show(b)} - |a2 = ${show(a2)} - |b2 = ${show(b2)} - |rem1 = ${show(rem1)} - |rem2 = ${show(rem2)} - | - |a = ${a.toString} - |b = ${b.toString} - |a2 = ${a2.toString} - |b2 = ${b2.toString} - |rem1 = ${rem1.toString} - |rem2 = ${rem2.toString} + |a = $a + |b = $b + |a2 = $a2 + |b2 = $b2 + |rem1 = $rem1 + |rem2 = $rem2 | |""".stripMargin, res1, res2) } diff --git a/tests/patmat/aliasing.check b/tests/patmat/aliasing.check index c367626d6f1e..018905abf47e 100644 --- a/tests/patmat/aliasing.check +++ b/tests/patmat/aliasing.check @@ -1,3 +1,3 @@ -14: Pattern Match Exhaustivity: _: Trait & Test.Alias1, _: Clazz & Test.Alias1 -19: Pattern Match Exhaustivity: _: Trait & Test.Alias2 -23: Pattern Match Exhaustivity: _: Trait & (Test.Alias2 & OpenTrait2){val x: Int} +14: Pattern Match Exhaustivity: _: Trait & Alias1, _: Clazz & Alias1 +19: Pattern Match Exhaustivity: _: Trait & Alias2 +23: Pattern Match Exhaustivity: _: Trait & (Alias2 & OpenTrait2){val x: Int} diff --git a/tests/patmat/i12020.check b/tests/patmat/i12020.check index b89bdc8314e5..13b07e2e5992 100644 --- a/tests/patmat/i12020.check +++ b/tests/patmat/i12020.check @@ -1 +1 @@ -19: Pattern Match Exhaustivity: _: TypeDef +19: Pattern Match Exhaustivity: _: x$1.reflect.TypeDef diff --git a/tests/patmat/i2502.check b/tests/patmat/i2502.check index fe2194e650cf..56cd3f6c0b8c 100644 --- a/tests/patmat/i2502.check +++ b/tests/patmat/i2502.check @@ -1 +1 @@ -5: Pattern Match Exhaustivity: _: BTypes.ClassBType \ No newline at end of file +5: Pattern Match Exhaustivity: _: BTypes.this.ClassBType diff --git a/tests/patmat/i2502b.check b/tests/patmat/i2502b.check index fe2194e650cf..56cd3f6c0b8c 100644 --- a/tests/patmat/i2502b.check +++ b/tests/patmat/i2502b.check @@ -1 +1 @@ -5: Pattern Match Exhaustivity: _: BTypes.ClassBType \ No newline at end of file +5: Pattern Match Exhaustivity: _: BTypes.this.ClassBType diff --git a/tests/patmat/i3938.check b/tests/patmat/i3938.check index 5aaefe2263e1..2acd1040ead4 100644 --- a/tests/patmat/i3938.check +++ b/tests/patmat/i3938.check @@ -1 +1 @@ -34: Pattern Match Exhaustivity: bar.C() +34: Pattern Match Exhaustivity: foo.bar.C() diff --git a/tests/patmat/i6255b.check b/tests/patmat/i6255b.check index 265ec9fa9c4b..bd9585becc56 100644 --- a/tests/patmat/i6255b.check +++ b/tests/patmat/i6255b.check @@ -1 +1 @@ -3: Pattern Match Exhaustivity: _: Expr[Int] +3: Pattern Match Exhaustivity: _: scala.quoted.Expr[Int] diff --git a/tests/patmat/t10100.check b/tests/patmat/t10100.check index d11715a5f371..19a89cd08a74 100644 --- a/tests/patmat/t10100.check +++ b/tests/patmat/t10100.check @@ -1 +1 @@ -12: Pattern Match Exhaustivity: (_, FancyFoo(_)) +12: Pattern Match Exhaustivity: (_, NonExhaustive#FancyFoo(_)) diff --git a/tests/patmat/t9779.check b/tests/patmat/t9779.check index 63f3b8963cac..c1886064d8ef 100644 --- a/tests/patmat/t9779.check +++ b/tests/patmat/t9779.check @@ -1 +1 @@ -10: Pattern Match Exhaustivity: _: a.Elem[_] +10: Pattern Match Exhaustivity: _: a.Elem[?]