From 51e5aa895d4afe492a9387d7a39df1894e585918 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 17 Apr 2019 11:35:23 +0200 Subject: [PATCH 1/2] Fix #6325: Propagate error type to internal splice --- compiler/src/dotty/tools/dotc/ast/tpd.scala | 4 +++- tests/neg/i6325.scala | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 tests/neg/i6325.scala diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala index 6a2faa74b13e..ca505ef69529 100644 --- a/compiler/src/dotty/tools/dotc/ast/tpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala @@ -1181,7 +1181,9 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { /** An extractor for typed splices */ object Splice { def apply(tree: Tree)(implicit ctx: Context): Tree = { - val argType = tree.tpe.baseType(defn.QuotedExprClass).argTypesHi.head + val argType = + if (tree.tpe.widen.isError) tree.tpe.widen + else tree.tpe.baseType(defn.QuotedExprClass).argTypesHi.head ref(defn.InternalQuoted_exprSplice).appliedToType(argType).appliedTo(tree) } def unapply(tree: Tree)(implicit ctx: Context): Option[Tree] = tree match { diff --git a/tests/neg/i6325.scala b/tests/neg/i6325.scala new file mode 100644 index 000000000000..9f858fa513d3 --- /dev/null +++ b/tests/neg/i6325.scala @@ -0,0 +1,7 @@ +//import scala.quoted.matching.Bind +object Test { + def res(x: quoted.Expr[Int]) given tasty.Reflection: quoted.Expr[Int] = x match { + case '{ 1 + (${Bind(b)}: Int) } => ??? // error: Not found: Bind + case _ => ??? + } +} From c5251ea05b5bdcf4ef71eacbd4c0fbe248eff74a Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 17 Apr 2019 11:48:35 +0200 Subject: [PATCH 2/2] Fix #6324: Emit error when pattern splice prototype is not fully defined Previously it was an assertion which crashed the compilation --- compiler/src/dotty/tools/dotc/typer/Typer.scala | 16 ++++++++++------ tests/neg/i6324.scala | 6 ++++++ 2 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 tests/neg/i6324.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index cba107ac2623..5445b693e7d4 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -2011,12 +2011,16 @@ class Typer extends Namer typed(innerExpr, pt) 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).withOwner(spliceOwner(ctx))) - Splice(pat) + if (isFullyDefined(pt, ForceDegree.all)) { + 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).withOwner(spliceOwner(ctx))) + Splice(pat) + } else { + ctx.error(i"Type must be fully defined.\nConsider annotating the splice using a type ascription:\n ($tree: XYZ).", expr.sourcePos) + tree.withType(UnspecifiedErrorType) + } } else typedApply(untpd.Apply(untpd.ref(defn.InternalQuoted_exprSpliceR), tree.expr), pt)(spliceContext).withSpan(tree.span) diff --git a/tests/neg/i6324.scala b/tests/neg/i6324.scala new file mode 100644 index 000000000000..6ffab1c2a860 --- /dev/null +++ b/tests/neg/i6324.scala @@ -0,0 +1,6 @@ +class Test { + def res(x: quoted.Expr[Int]) given tasty.Reflection: quoted.Expr[Int] = x match { + case '{ 1 + $b } => // error: Type must be fully defined. Consider annotating the splice using a type ascription: (${b}: XYZ). + b // error: Not found: b + } +} \ No newline at end of file