Skip to content

Commit 5415988

Browse files
committed
Fix #8100: Handle explicit paths in quotes
1 parent e7a0f80 commit 5415988

File tree

6 files changed

+56
-6
lines changed

6 files changed

+56
-6
lines changed

compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1204,7 +1204,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend
12041204
case tpe: Types.ConstantType => Some(tpe)
12051205
case _ => None
12061206
}
1207-
1207+
12081208
def ConstantType_apply(const: Constant)(given Context): ConstantType =
12091209
Types.ConstantType(const)
12101210

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import dotty.tools.dotc.core.Contexts._
99
import dotty.tools.dotc.core.Decorators._
1010
import dotty.tools.dotc.core.Flags._
1111
import dotty.tools.dotc.core.quoted._
12+
import dotty.tools.dotc.core.Mode
1213
import dotty.tools.dotc.core.NameKinds._
1314
import dotty.tools.dotc.core.StagingContext._
1415
import dotty.tools.dotc.core.StdNames._
@@ -49,7 +50,10 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
4950
case annot => transform(annot.tree)(given annotCtx)
5051
}
5152
checkLevel(super.transform(tree))
52-
case _ => checkLevel(super.transform(tree))
53+
case _ =>
54+
val ctx1 = if tree.isType then ctx.addMode(Mode.Type) else ctx
55+
given Context = ctx1
56+
checkLevel(super.transform(tree))
5357
}
5458

5559
/** Transform quoted trees while maintaining phase correctness */
@@ -100,7 +104,7 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
100104
case Some(tpRef) => tpRef
101105
case _ => tree
102106
}
103-
case _: TypeTree | _: AppliedTypeTree | _: Apply | _: TypeApply | _: UnApply | Select(_, OuterSelectName(_, _)) =>
107+
case _: TypeTree | _: AppliedTypeTree | _: Apply | _: UnApply | Select(_, OuterSelectName(_, _)) =>
104108
tree.withType(checkTp(tree.tpe))
105109
case _: ValOrDefDef | _: Bind =>
106110
tree.symbol.info = checkTp(tree.symbol.info)
@@ -179,6 +183,7 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
179183
case tp: TypeRef =>
180184
if levelOf(sym).getOrElse(0) < level then tryHeal(sym, tp, pos)
181185
else None
186+
case _: TermRef if ctx.mode.is(Mode.Type) && levelOf(sym).getOrElse(0) >= level => None
182187
case _ =>
183188
levelError(sym, tp, pos, "")
184189
else if (!sym.owner.isStaticOwner) // non-top level class reference that is phase inconsistent

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,7 @@ class ReifyQuotes extends MacroTransform {
231231
if (isType) ref(defn.Unpickler_unpickleType).appliedToType(originalTp)
232232
else ref(defn.Unpickler_unpickleExpr).appliedToType(originalTp.widen)
233233
val spliceResType =
234-
if (isType) defn.QuotedTypeClass.typeRef.appliedTo(WildcardType)
235-
else defn.FunctionType(1, isContextual = true).appliedTo(defn.QuoteContextClass.typeRef, defn.QuotedExprClass.typeRef.appliedTo(defn.AnyType)) | defn.QuotedTypeClass.typeRef.appliedTo(WildcardType)
234+
defn.FunctionType(1, isContextual = true).appliedTo(defn.QuoteContextClass.typeRef, defn.QuotedExprClass.typeRef.appliedTo(defn.AnyType)) | defn.QuotedTypeClass.typeRef.appliedTo(WildcardType)
236235
val pickledQuoteStrings = liftList(PickledQuotes.pickleQuote(body).map(x => Literal(Constant(x))), defn.StringType)
237236
val splicesList = liftList(splices, defn.FunctionType(1).appliedTo(defn.SeqType.appliedTo(defn.AnyType), spliceResType))
238237
meth.appliedTo(pickledQuoteStrings, splicesList)

library/src/scala/internal/quoted/Unpickler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ object Unpickler {
77

88
type PickledQuote = List[String]
99
type PickledExprArgs = Seq[Seq[Any] => (((given QuoteContext) => Expr[Any]) | Type[_])]
10-
type PickledTypeArgs = Seq[Seq[Any] => Type[_]]
10+
type PickledTypeArgs = Seq[Seq[Any] => (((given QuoteContext) => Expr[Any]) | Type[_])]
1111

1212
/** Unpickle `repr` which represents a pickled `Expr` tree,
1313
* replacing splice nodes with `args`

tests/neg/i8100.scala

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
2+
import scala.quoted._
3+
import scala.quoted.matching._
4+
5+
class M {
6+
type E
7+
}
8+
9+
def f[T: Type] with QuoteContext =
10+
summonExpr[M] match
11+
case Some('{ $mm : $tt }) =>
12+
'{
13+
val m = $mm
14+
${ val b: m.type =
15+
m // error
16+
???
17+
}
18+
}
19+
20+
21+
def g[T] with Type[T] = ???

tests/pos/i8100.scala

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
import scala.quoted._
3+
import scala.quoted.matching._
4+
5+
class M {
6+
type E
7+
}
8+
9+
def f with QuoteContext : Expr[Any] =
10+
val mm: Expr[M] = ???
11+
'{
12+
val m: M = $mm
13+
type ME = m.E
14+
${ g[ME](given '[ME]) }
15+
${ g[m.E](given '[ME]) }
16+
${ g[ME](given '[m.E]) }
17+
${ g[m.E](given '[m.E]) }
18+
// ${ g[ME] } // FIXME
19+
// ${ g[m.E] } // FIXME
20+
${ g(given '[ME]) }
21+
${ g(given '[m.E]) }
22+
}
23+
24+
25+
def g[T] with Type[T] = ???

0 commit comments

Comments
 (0)