From 1d7ef8b342d7d6dd69f79fdfc11dd6acb2307779 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 30 Aug 2021 13:24:30 +0200 Subject: [PATCH] Revert "Remove unnecessary type from UnApply" This reverts commit aeb3db1cbfe6a15895e3dd2d3206e7b017d1a56f. Fixes #13405 --- compiler/src/dotty/tools/dotc/ast/tpd.scala | 4 ++-- .../tools/dotc/core/tasty/TreePickler.scala | 3 +-- .../tools/dotc/core/tasty/TreeUnpickler.scala | 4 ++-- .../core/unpickleScala2/Scala2Unpickler.scala | 2 +- .../tools/dotc/typer/QuotesAndSplices.scala | 17 ++++++----------- .../scala/quoted/runtime/impl/QuotesImpl.scala | 2 +- .../dotc/BootstrappedOnlyCompilationTests.scala | 1 + tests/pos-custom-args/i13405/Macro.scala | 12 ++++++++++++ tests/pos-custom-args/i13405/Test.scala | 1 + 9 files changed, 27 insertions(+), 19 deletions(-) create mode 100644 tests/pos-custom-args/i13405/Macro.scala create mode 100644 tests/pos-custom-args/i13405/Test.scala diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala index 0a7beba3a8b9..0c12eff2a0ae 100644 --- a/compiler/src/dotty/tools/dotc/ast/tpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala @@ -197,9 +197,9 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { def Alternative(trees: List[Tree])(using Context): Alternative = ta.assignType(untpd.Alternative(trees), trees) - def UnApply(fun: Tree, implicits: List[Tree], patterns: List[Tree])(using Context): UnApply = { + def UnApply(fun: Tree, implicits: List[Tree], patterns: List[Tree], proto: Type)(using Context): UnApply = { assert(fun.isInstanceOf[RefTree] || fun.isInstanceOf[GenericApply]) - ta.assignType(untpd.UnApply(fun, implicits, patterns), defn.NothingType) + ta.assignType(untpd.UnApply(fun, implicits, patterns), proto) } def ValDef(sym: TermSymbol, rhs: LazyTree = EmptyTree)(using Context): ValDef = diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala index 18db42f9e276..a195b157cacd 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala @@ -538,8 +538,7 @@ class TreePickler(pickler: TastyPickler) { writeByte(IMPLICITarg) pickleTree(implicitArg) } - // TODO write a dummy type that takes less space? - pickleType(tree.tpe) // IGNORED // TODO remove when we can break TASTy compat. + pickleType(tree.tpe) patterns.foreach(pickleTree) } case tree: ValDef => diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index 3d09d9ac1589..e4a5c0ae8c6d 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -1246,9 +1246,9 @@ class TreeUnpickler(reader: TastyReader, readByte() readTerm() } - val patType = readType() // IGNORED // TODO remove when we can break TASTy compat. + val patType = readType() val argPats = until(end)(readTerm()) - UnApply(fn, implicitArgs, argPats) + UnApply(fn, implicitArgs, argPats, patType) case REFINEDtpt => val refineCls = symAtAddr.getOrElse(start, newRefinedClassSymbol(coordAt(start))).asClass diff --git a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala index 738c8a158960..1a70fb1e9d2d 100644 --- a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala @@ -1175,7 +1175,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas case UNAPPLYtree => val fun = readTreeRef() val args = until(end, () => readTreeRef()) - UnApply(fun, Nil, args) + UnApply(fun, Nil, args, defn.AnyType) // !!! this is wrong in general case ARRAYVALUEtree => val elemtpt = readTreeRef() diff --git a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala index 919469529cb5..9c60374d9a9a 100644 --- a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala +++ b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala @@ -400,11 +400,8 @@ trait QuotesAndSplices { * }, * true, // If there is at least one type splice. Used to instantiate the context with or without GADT constraints * x$2 // tasty.Reflection instance - * ): Expr[S & List[t] @unchecked] => ... + * ) => ... * ``` - * - * For a scrutinee of type `S`, the `: Expr[S & List[t] @unchecked]` tells the pattern that if the pattern matched the bound - * scrutinee `x @ '{..}` is of type `Expr[S & List[t] @unchecked]`. */ private def typedQuotePattern(tree: untpd.Quote, pt: Type, qctx: Tree)(using Context): Tree = { if tree.quoted.isTerm && !pt.derivesFrom(defn.QuotedExprClass) then @@ -472,12 +469,10 @@ trait QuotesAndSplices { val matchModule = if tree.quoted.isTerm then defn.QuoteMatching_ExprMatch else defn.QuoteMatching_TypeMatch val unapplyFun = qctx.asInstance(defn.QuoteMatchingClass.typeRef).select(matchModule).select(nme.unapply) - Typed( - UnApply( - fun = unapplyFun.appliedToTypeTrees(typeBindingsTuple :: TypeTree(patType) :: Nil), - implicits = quotedPattern :: Nil, - patterns = splicePat :: Nil), - TypeTree(quoteClass.typeRef.appliedTo(replaceBindings(quoted1.tpe) & quotedPt)) - ).annotated(New(defn.UncheckedAnnot.typeRef, Nil)) + UnApply( + fun = unapplyFun.appliedToTypeTrees(typeBindingsTuple :: TypeTree(patType) :: Nil), + implicits = quotedPattern :: Nil, + patterns = splicePat :: Nil, + proto = quoteClass.typeRef.appliedTo(replaceBindings(quoted1.tpe) & quotedPt)) } } diff --git a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala index 5b6deb7bc526..4c16871db1d1 100644 --- a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala +++ b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala @@ -1484,7 +1484,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler object Unapply extends UnapplyModule: def apply(fun: Term, implicits: List[Term], patterns: List[Tree]): Unapply = - withDefaultPos(tpd.UnApply(fun, implicits, patterns)) + withDefaultPos(tpd.UnApply(fun, implicits, patterns, dotc.core.Symbols.defn.NothingType)) def copy(original: Tree)(fun: Term, implicits: List[Term], patterns: List[Tree]): Unapply = withDefaultPos(tpd.cpy.UnApply(original)(fun, implicits, patterns)) def unapply(x: Unapply): (Term, List[Term], List[Tree]) = diff --git a/compiler/test/dotty/tools/dotc/BootstrappedOnlyCompilationTests.scala b/compiler/test/dotty/tools/dotc/BootstrappedOnlyCompilationTests.scala index b16fb62f1dcd..9a6da578348c 100644 --- a/compiler/test/dotty/tools/dotc/BootstrappedOnlyCompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/BootstrappedOnlyCompilationTests.scala @@ -29,6 +29,7 @@ class BootstrappedOnlyCompilationTests { compileFilesInDir("tests/pos-custom-args/semanticdb", defaultOptions.and("-Xsemanticdb")), compileDir("tests/pos-special/i7592", defaultOptions.and("-Yretain-trees")), compileDir("tests/pos-special/i11331.1", defaultOptions), + compileDir("tests/pos-custom-args/i13405", defaultOptions.and("-Xfatal-warnings")), ).checkCompile() } diff --git a/tests/pos-custom-args/i13405/Macro.scala b/tests/pos-custom-args/i13405/Macro.scala new file mode 100644 index 000000000000..2996555a6e0c --- /dev/null +++ b/tests/pos-custom-args/i13405/Macro.scala @@ -0,0 +1,12 @@ +import scala.quoted.* + +sealed class Foo() +inline def hh(): Unit = ${ interpMacro() } + +private def interpMacro()(using Quotes): Expr[Unit] = + import quotes.reflect.* + '{ + val res: Either[String, (Foo, Foo)] = + Right((new Foo, new Foo)) + val (a, b) = res.toOption.get + } diff --git a/tests/pos-custom-args/i13405/Test.scala b/tests/pos-custom-args/i13405/Test.scala new file mode 100644 index 000000000000..385f4453adeb --- /dev/null +++ b/tests/pos-custom-args/i13405/Test.scala @@ -0,0 +1 @@ +@main def main: Unit = hh()