From 06b5684b47f4d49ae3d67cc11ee54905a81c35b5 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 6 Mar 2023 11:42:27 +0100 Subject: [PATCH] Avoid creation of `@SplicedType` quote local refrences The type declarations annotated with `@SplicedType` are only meant for types that come from outside the quote. If the reference to the `Type[T]` is to a definition within the quote (i.e. its level is grater than 0) we can use it directly. The `@SplicedType` for that type will be generated in a future compilation phase when the `Type[T]` definition reaches level 0. Fixes #17026 --- compiler/src/dotty/tools/dotc/staging/HealType.scala | 6 ++++-- tests/pos-macros/i17026.scala | 3 +++ tests/pos-macros/i17026b.scala | 7 +++++++ 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 tests/pos-macros/i17026.scala create mode 100644 tests/pos-macros/i17026b.scala diff --git a/compiler/src/dotty/tools/dotc/staging/HealType.scala b/compiler/src/dotty/tools/dotc/staging/HealType.scala index 44843dfa91ca..22008f381c32 100644 --- a/compiler/src/dotty/tools/dotc/staging/HealType.scala +++ b/compiler/src/dotty/tools/dotc/staging/HealType.scala @@ -4,6 +4,7 @@ package staging import dotty.tools.dotc.core.Contexts._ import dotty.tools.dotc.core.Decorators._ import dotty.tools.dotc.core.Flags._ +import dotty.tools.dotc.core.StdNames._ import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.core.Types._ import dotty.tools.dotc.staging.QuoteContext.* @@ -68,13 +69,14 @@ class HealType(pos: SrcPos)(using Context) extends TypeMap { * reference to a type alias containing the equivalent of `${summon[quoted.Type[T]]}`. * Emits an error if `T` cannot be healed and returns `T`. */ - protected def tryHeal(sym: Symbol, tp: TypeRef, pos: SrcPos): TypeRef = { + protected def tryHeal(sym: Symbol, tp: TypeRef, pos: SrcPos): Type = { val reqType = defn.QuotedTypeClass.typeRef.appliedTo(tp) val tag = ctx.typer.inferImplicitArg(reqType, pos.span) tag.tpe match case tp: TermRef => ctx.typer.checkStable(tp, pos, "type witness") - getQuoteTypeTags.getTagRef(tp) + if levelOf(tp.symbol) > 0 then tp.select(tpnme.Underlying) + else getQuoteTypeTags.getTagRef(tp) case _: SearchFailureType => report.error( ctx.typer.missingArgMsg(tag, reqType, "") diff --git a/tests/pos-macros/i17026.scala b/tests/pos-macros/i17026.scala new file mode 100644 index 000000000000..d8845ef1d086 --- /dev/null +++ b/tests/pos-macros/i17026.scala @@ -0,0 +1,3 @@ +import scala.quoted.* +def macroImpl(using Quotes) = + '{ def weird[A: Type](using Quotes) = Type.of[A] } diff --git a/tests/pos-macros/i17026b.scala b/tests/pos-macros/i17026b.scala new file mode 100644 index 000000000000..98a29066462e --- /dev/null +++ b/tests/pos-macros/i17026b.scala @@ -0,0 +1,7 @@ +import scala.quoted.* + +def macroImpl(using Quotes) = + '{ + def weird[A: ToExpr: Type](a: A)(using quotes: Quotes) = + '{ Some(${ Expr(a) }) } + }