From 145db07a502dc57b0f7ca6fcf41b15f00851858d Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 6 Apr 2019 10:32:05 +0200 Subject: [PATCH 1/2] Fix #6214: Set correct owner for splices in quote patterns --- compiler/src/dotty/tools/dotc/typer/Typer.scala | 4 +++- tests/pos/i6214.scala | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i6214.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index effe488555ab..075d2da3c37d 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1988,8 +1988,10 @@ class Typer extends Namer case expr => if (ctx.mode.is(Mode.QuotedPattern) && level == 1) { fullyDefinedType(pt, "quoted pattern selector", tree.span) + def spliceOwner(ctx: Context): Symbol = + if (ctx.mode.is(Mode.QuotedPattern)) spliceOwner(ctx.outer) else ctx.owner val pat = typedPattern(expr, defn.QuotedExprType.appliedTo(pt))( - spliceContext.retractMode(Mode.QuotedPattern)) + spliceContext.retractMode(Mode.QuotedPattern).withOwner(spliceOwner(ctx))) Splice(pat) } else diff --git a/tests/pos/i6214.scala b/tests/pos/i6214.scala new file mode 100644 index 000000000000..16e6140e3e82 --- /dev/null +++ b/tests/pos/i6214.scala @@ -0,0 +1,7 @@ +import scala.quoted._ +object Test { + def res(x: quoted.Expr[Int]) given tasty.Reflection: quoted.Expr[Int] = x match { + case '{ val a: Int = $y; 1} => y // owner of `y` is `res` + case _ => '{ val b: Int = ${val c = 2; c.toExpr}; 1} // owner of `c` is `b`, but that seems to be OK + } +} \ No newline at end of file From ade87abccc9e69a07fdc1a4c9902d279274213d2 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Sat, 6 Apr 2019 11:33:37 +0200 Subject: [PATCH 2/2] Add a test on nested quoted patterns --- tests/pos/i6214b.scala | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tests/pos/i6214b.scala diff --git a/tests/pos/i6214b.scala b/tests/pos/i6214b.scala new file mode 100644 index 000000000000..276367fe350a --- /dev/null +++ b/tests/pos/i6214b.scala @@ -0,0 +1,8 @@ +object Test { + def res(x: quoted.Expr[Int]) given tasty.Reflection: quoted.Expr[Int] = x match { + case '{ val a: Int = ${ Foo('{ val b: Int = $y; b }) }; a } => y // owner of y is res + } + object Foo { + def unapply(x: quoted.Expr[Int]): Option[quoted.Expr[Int]] = Some(x) + } +}