From 79cbafcddc740ab4df1d4cc0f57b7d54dcd36007 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 27 Apr 2021 09:13:30 +0200 Subject: [PATCH] Fix internal definition of `Unapply` Remove old workaround for `Unapply`. Users may see an extra `Typed` in the trees of patterns Fixes #12221 --- .../quoted/runtime/impl/QuotesImpl.scala | 28 +++++++------------ .../runtime/impl/printers/SourceCode.scala | 3 ++ library/src/scala/quoted/Quotes.scala | 2 +- tests/run-staging/i5161.check | 2 +- 4 files changed, 15 insertions(+), 20 deletions(-) diff --git a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala index 6fdf2225bbdf..fed05b4492fd 100644 --- a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala +++ b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala @@ -333,13 +333,11 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler object TermTypeTest extends TypeTest[Tree, Term]: def unapply(x: Tree): Option[Term & x.type] = x match - case _ if UnapplyTypeTest.unapply(x).isDefined => None - case _: tpd.PatternTree => None - case x: (tpd.Tree & x.type) if x.isTerm => Some(x) + case x: tpd.PatternTree => None case x: (tpd.SeqLiteral & x.type) => Some(x) case x: (tpd.Inlined & x.type) => Some(x) case x: (tpd.NamedArg & x.type) => Some(x) - case _ => None + case _ => if x.isTerm then Some(x) else None end TermTypeTest object Term extends TermModule: @@ -1424,14 +1422,12 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler end extension end BindMethods - type Unapply = tpd.UnApply | tpd.Typed // tpd.Typed containing a tpd.UnApply as expression + type Unapply = tpd.UnApply object UnapplyTypeTest extends TypeTest[Tree, Unapply]: - def unapply(x: Tree): Option[Unapply & x.type] = - x match // keep in sync with UnapplyMethodsImpl.selfUnApply - case x: (tpd.UnApply & x.type) => Some(x) - case x: (tpd.Typed & x.type) if x.expr.isInstanceOf[tpd.UnApply] => Some(x) - case _ => None + def unapply(x: Tree): Option[Unapply & x.type] = x match + case x: (tpd.UnApply & x.type) => Some(x) + case _ => None end UnapplyTypeTest object Unapply extends UnapplyModule: @@ -1443,14 +1439,10 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler given UnapplyMethods: UnapplyMethods with extension (self: Unapply) - def fun: Term = selfUnApply(self).fun - def implicits: List[Term] = selfUnApply(self).implicits - def patterns: List[Tree] = effectivePatterns(selfUnApply(self).patterns) - end extension - private def selfUnApply(self: Unapply): tpd.UnApply = - self match // keep in sync with UnapplyTypeTest - case self: tpd.UnApply => self - case self: tpd.Typed => self.expr.asInstanceOf[tpd.UnApply] + def fun: Term = self.fun + def implicits: List[Term] = self.implicits + def patterns: List[Tree] = effectivePatterns(self.patterns) + end extension private def effectivePatterns(patterns: List[Tree]): List[Tree] = patterns match case patterns0 :+ dotc.ast.Trees.SeqLiteral(elems, _) => patterns0 ::: elems diff --git a/compiler/src/scala/quoted/runtime/impl/printers/SourceCode.scala b/compiler/src/scala/quoted/runtime/impl/printers/SourceCode.scala index 62fa24d908f1..bc911552a614 100644 --- a/compiler/src/scala/quoted/runtime/impl/printers/SourceCode.scala +++ b/compiler/src/scala/quoted/runtime/impl/printers/SourceCode.scala @@ -530,6 +530,9 @@ object SourceCode { case Closure(meth, _) => printTree(meth) + case _:Unapply | _:Alternatives | _:Bind => + printPattern(tree) + case _ => throw new MatchError(tree.show(using Printer.TreeStructure)) diff --git a/library/src/scala/quoted/Quotes.scala b/library/src/scala/quoted/Quotes.scala index 96424a176b35..7c4733255559 100644 --- a/library/src/scala/quoted/Quotes.scala +++ b/library/src/scala/quoted/Quotes.scala @@ -4359,7 +4359,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => case New(tpt) => New.copy(tree)(transformTypeTree(tpt)(owner)) case Typed(expr, tpt) => - Typed.copy(tree)(transformTerm(expr)(owner), transformTypeTree(tpt)(owner)) + Typed.copy(tree)(/*FIXME #12222: transformTerm(expr)(owner)*/transformTree(expr)(owner).asInstanceOf[Term], transformTypeTree(tpt)(owner)) case tree: NamedArg => NamedArg.copy(tree)(tree.name, transformTerm(tree.value)(owner)) case Assign(lhs, rhs) => diff --git a/tests/run-staging/i5161.check b/tests/run-staging/i5161.check index 27c72498d7f1..a178c827d633 100644 --- a/tests/run-staging/i5161.check +++ b/tests/run-staging/i5161.check @@ -1,6 +1,6 @@ run : Some(2) show : scala.Tuple2.apply[scala.Option[scala.Int], scala.Option[scala.Int]](scala.Some.apply[scala.Int](1), scala.Some.apply[scala.Int](1)) match { - case scala.Tuple2(scala.Some(x), scala.Some(y)) => + case scala.Tuple2((scala.Some(x): scala.Some[scala.Int]), (scala.Some(y): scala.Some[scala.Int])) => scala.Some.apply[scala.Int](x.+(y)) case _ => scala.None