From 50c646417a9d7229b32ba6276b8364a65be5f957 Mon Sep 17 00:00:00 2001 From: odersky Date: Thu, 24 Mar 2022 09:28:00 +0100 Subject: [PATCH] Drop special treatment for Scala-2 code in unapply It seems our GADT handling is now able to do without. Fixes #14693 --- compiler/src/dotty/tools/dotc/core/TypeOps.scala | 2 +- .../src/dotty/tools/dotc/transform/TypeTestsCasts.scala | 2 +- compiler/src/dotty/tools/dotc/typer/Applications.scala | 4 +--- compiler/src/dotty/tools/dotc/typer/Inferencing.scala | 4 ++-- tests/run/i14693.check | 1 + tests/run/i14693.scala | 9 +++++++++ 6 files changed, 15 insertions(+), 7 deletions(-) create mode 100644 tests/run/i14693.check create mode 100644 tests/run/i14693.scala diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala index c13d005fa5ac..2cfdd08128ce 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala @@ -827,7 +827,7 @@ object TypeOps: } def instantiate(): Type = { - maximizeType(protoTp1, NoSpan, fromScala2x = false) + maximizeType(protoTp1, NoSpan) wildApprox(protoTp1) } diff --git a/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala b/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala index 4db3e9b80c9d..371982a8b442 100644 --- a/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala +++ b/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala @@ -109,7 +109,7 @@ object TypeTestsCasts { // which conform to the skeleton pre.F[_] and X. Then we have to make // sure all of them are actually of the type P, which implies that the // type arguments in P are trivial (no runtime check needed). - maximizeType(P1, span, fromScala2x = false) + maximizeType(P1, span) debug.println("after " + ctx.typerState.constraint.show) diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index 2cf1050a5c67..68c4b357b782 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -1326,8 +1326,6 @@ trait Applications extends Compatibility { unapp } - def fromScala2x = unapplyFn.symbol.exists && (unapplyFn.symbol.owner is Scala2x) - unapplyFn.tpe.widen match { case mt: MethodType if mt.paramInfos.length == 1 => val unapplyArgType = mt.paramInfos.head @@ -1343,7 +1341,7 @@ trait Applications extends Compatibility { // Constraining only fails if the pattern cannot possibly match, // but useless pattern checks detect more such cases, so we simply rely on them instead. withMode(Mode.GadtConstraintInference)(TypeComparer.constrainPatternType(unapplyArgType, selType)) - val patternBound = maximizeType(unapplyArgType, tree.span, fromScala2x) + val patternBound = maximizeType(unapplyArgType, tree.span) if (patternBound.nonEmpty) unapplyFn = addBinders(unapplyFn, patternBound) unapp.println(i"case 2 $unapplyArgType ${ctx.typerState.constraint}") unapplyArgType diff --git a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala index 733b95995f05..043f931113ab 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala @@ -399,7 +399,7 @@ object Inferencing { * @return The list of type symbols that were created * to instantiate undetermined type variables that occur non-variantly */ - def maximizeType(tp: Type, span: Span, fromScala2x: Boolean)(using Context): List[Symbol] = { + def maximizeType(tp: Type, span: Span)(using Context): List[Symbol] = { Stats.record("maximizeType") val vs = variances(tp) val patternBindings = new mutable.ListBuffer[(Symbol, TypeParamRef)] @@ -409,7 +409,7 @@ object Inferencing { else if (v == -1) tvar.instantiate(fromBelow = true) else { val bounds = TypeComparer.fullBounds(tvar.origin) - if (bounds.hi <:< bounds.lo || bounds.hi.classSymbol.is(Final) || fromScala2x) + if bounds.hi <:< bounds.lo || bounds.hi.classSymbol.is(Final) then tvar.instantiate(fromBelow = false) else { // We do not add the created symbols to GADT constraint immediately, since they may have inter-dependencies. diff --git a/tests/run/i14693.check b/tests/run/i14693.check new file mode 100644 index 000000000000..f985b46aff02 --- /dev/null +++ b/tests/run/i14693.check @@ -0,0 +1 @@ +Success! diff --git a/tests/run/i14693.scala b/tests/run/i14693.scala new file mode 100644 index 000000000000..52d7ca6de4a6 --- /dev/null +++ b/tests/run/i14693.scala @@ -0,0 +1,9 @@ +object Test { + val a: Array[Long] = Array(1L) + + def test(x: Any) = x match { + case Array(i: Long) => println("Success!") + case _ => println("Failure!") } + + def main(args: Array[String]): Unit = test(a) +} \ No newline at end of file