Skip to content

Commit c59265d

Browse files
committed
WIP Fix scala#5247: Splice typed directly in the tree
Remove addTags logic
1 parent 7027670 commit c59265d

File tree

6 files changed

+58
-18
lines changed

6 files changed

+58
-18
lines changed

compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ object PickledQuotes {
3232
def pickleQuote(tree: Tree)(implicit ctx: Context): scala.runtime.quoted.Unpickler.Pickled = {
3333
if (ctx.reporter.hasErrors) Nil
3434
else {
35-
assert(!tree.isInstanceOf[Hole]) // Should not be pickled as it represents `'(~x)` which should be optimized to `x`
35+
// assert(!tree.isInstanceOf[Hole], "missed optimization opportunity") // Should not be pickled as it represents `'(~x)` which should be optimized to `x`
3636
val pickled = pickle(tree)
3737
TastyString.pickle(pickled)
3838
}

compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -253,10 +253,10 @@ class ReifyQuotes extends MacroTransformWithImplicits {
253253

254254
/** Try to heal phase-inconsistent reference to type `T` using a local type definition.
255255
* @return None if successful
256-
* @return Some(msg) if unsuccessful where `msg` is a potentially empty error message
257-
* to be added to the "inconsistent phase" message.
256+
* @return Some(Left(msg)) if unsuccessful where `msg` is a potentially empty error message
257+
* @return Some(Right(ttag)) the type tag that heals the inconcistency
258258
*/
259-
def tryHeal(tp: Type, pos: Position)(implicit ctx: Context): Option[String] = tp match {
259+
def tryHeal(tp: Type, pos: Position)(implicit ctx: Context): Option[Either[String, Tree]] = tp match {
260260
case tp: TypeRef =>
261261
if (level == -1) {
262262
assert(ctx.inInlineMethod)
@@ -266,37 +266,43 @@ class ReifyQuotes extends MacroTransformWithImplicits {
266266
val tag = ctx.typer.inferImplicitArg(reqType, pos)
267267
tag.tpe match {
268268
case fail: SearchFailureType =>
269-
Some(i"""
269+
Some(Left(i"""
270270
|
271271
| The access would be accepted with the right type tag, but
272-
| ${ctx.typer.missingArgMsg(tag, reqType, "")}""")
272+
| ${ctx.typer.missingArgMsg(tag, reqType, "")}"""))
273273
case _ =>
274-
importedTags(tp) = nested(isQuote = false).transform(tag)
275-
None
274+
Some(Right(nested(isQuote = false).transform(tag)))
275+
276276
}
277277
}
278278
case _ =>
279-
Some("")
279+
Some(Left(""))
280280
}
281281

282282
/** Check reference to `sym` for phase consistency, where `tp` is the underlying type
283283
* by which we refer to `sym`.
284284
*/
285-
def check(sym: Symbol, tp: Type, pos: Position)(implicit ctx: Context): Unit = {
285+
def check(sym: Symbol, tp: Type, pos: Position)(implicit ctx: Context): Option[Tree] = {
286286
val isThis = tp.isInstanceOf[ThisType]
287287
def symStr =
288288
if (!isThis) sym.show
289289
else if (sym.is(ModuleClass)) sym.sourceModule.show
290290
else i"${sym.name}.this"
291-
if (!isThis && sym.maybeOwner.isType && !sym.is(Param))
291+
if (!isThis && sym.maybeOwner.isType && !sym.is(Param)) {
292292
check(sym.owner, sym.owner.thisType, pos)
293-
else if (level == 1 && sym.isType && sym.is(Param) && sym.owner.isInlineMethod && !outer.isRoot)
294-
importedTags(sym.typeRef) = capturers(sym)(ref(sym))
295-
else if (sym.exists && !sym.isStaticOwner && !levelOK(sym))
296-
for (errMsg <- tryHeal(tp, pos))
297-
ctx.error(em"""access to $symStr from wrong staging level:
293+
} else if (level == 1 && sym.isType && sym.is(Param) && sym.owner.isInlineMethod && !outer.isRoot) {
294+
Some(capturers(sym)(ref(sym)))
295+
} else if (sym.exists && !sym.isStaticOwner && !levelOK(sym)) {
296+
tryHeal(tp, pos) match {
297+
case Some(Left(errMsg)) =>
298+
ctx.error(em"""access to $symStr from wrong staging level:
298299
| - the definition is at level ${levelOf.getOrElse(sym, 0)},
299300
| - but the access is at level $level.$errMsg""", pos)
301+
None
302+
case Some(Right(ttag)) => Some(ttag)
303+
case None => None
304+
}
305+
} else None
300306
}
301307

302308
/** Check all named types and this-types in a given type for phase consistency. */
@@ -341,18 +347,26 @@ class ReifyQuotes extends MacroTransformWithImplicits {
341347
private def checkLevel(tree: Tree)(implicit ctx: Context): Tree = {
342348
tree match {
343349
case (_: Ident) | (_: This) =>
344-
check(tree.symbol, tree.tpe, tree.pos)
350+
check(tree.symbol, tree.tpe, tree.pos) match {
351+
case Some(ttag) =>
352+
transform(ttag.select(tpnme.UNARY_~))
353+
case _ => tree
354+
}
345355
case (_: UnApply) | (_: TypeTree) =>
346356
checkType(tree.pos).apply((), tree.tpe)
357+
tree
347358
case Select(qual, OuterSelectName(_, levels)) =>
348359
checkType(tree.pos).apply((), tree.tpe.widen)
360+
tree
349361
case _: Bind =>
350362
checkType(tree.pos).apply((), tree.symbol.info)
363+
tree
351364
case _: Template =>
352365
checkType(tree.pos).apply((), tree.symbol.owner.asClass.givenSelfType)
366+
tree
353367
case _ =>
368+
tree
354369
}
355-
tree
356370
}
357371

358372
/** Split `body` into a core and a list of embedded splices.

tests/run-with-compiler/i5247.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
null.asInstanceOf[java.lang.Object]

tests/run-with-compiler/i5247.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import scala.quoted._
2+
object Test {
3+
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make
4+
def main(args: Array[String]): Unit = {
5+
println(foo[Object].show)
6+
}
7+
def foo[H : Type]: Expr[H] = {
8+
val t = '[H]
9+
'{ null.asInstanceOf[~t] }
10+
}
11+
}

tests/run-with-compiler/quote-type-param-with-tag.check

Whitespace-only changes.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import scala.quoted._
2+
3+
object Test {
4+
def main(args: Array[String]): Unit = {
5+
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make
6+
foo[Object].show
7+
}
8+
9+
def foo[H](implicit t0: Type[H]): Expr[Tuple1[H]] = {
10+
val t = '[H]
11+
'{ null.asInstanceOf[~t] }
12+
}
13+
14+
}

0 commit comments

Comments
 (0)