@@ -33,28 +33,32 @@ import scala.annotation.constructorOnly
3333 * val x1: U1 = ???
3434 * val x2: U2 = ???
3535 * ...
36- * {{{ 3 | x1 | contents0 | T0 }}} // hole
36+ * {{{ 3 | T0 | x1 | contents0 }}} // hole
3737 * ...
38- * {{{ 4 | x2 | contents1 | T1 }}} // hole
38+ * {{{ 4 | T1 | x2 | contents1 }}} // hole
3939 * ...
40- * {{{ 5 | x1, x2 | contents2 | T2 }}} // hole
40+ * {{{ 5 | T2 | x1, x2 | contents2 | }}} // hole
41+ * ...
42+ * {{{ 6 | T2 | X0, x1 | contents2 | }}} // hole
4143 * ...
4244 * }
4345 * ```
4446 * to
4547 * ```
4648 * unpickleExprV2(
4749 * pickled = [[ // PICKLED TASTY
48- * @TypeSplice type X0 // with bounds that do not contain captured types
49- * @TypeSplice type X1 // with bounds that do not contain captured types
50+ * @TypeSplice type X0 = hole[0, ..] // with bounds that do not contain captured types
51+ * @TypeSplice type X1 = hole[1, ..] // with bounds that do not contain captured types
5052 * val x1 = ???
5153 * val x2 = ???
5254 * ...
53- * {{{ 0 | x1 | | T0 }}} // hole
54- * ...
55- * {{{ 1 | x2 | | T1 }}} // hole
56- * ...
57- * {{{ 2 | x1, x2 | | T2 }}} // hole
55+ * hole[3, T0, KNil](x1) // hole
56+ * ...
57+ * hole[4, T1, KNil](x2) // hole
58+ * ...
59+ * hole[5, T2, KNil](x1, x2) // hole
60+ * ...
61+ * hole[6, T2, KCons[X0, KNil]](x1) // hole
5862 * ...
5963 * ]],
6064 * typeHole = (idx: Int, args: List[Any]) => idx match {
@@ -65,6 +69,7 @@ import scala.annotation.constructorOnly
6569 * case 3 => content0.apply(args(0).asInstanceOf[Expr[U1]]).apply(quotes) // beta reduced
6670 * case 4 => content1.apply(args(0).asInstanceOf[Expr[U2]]).apply(quotes) // beta reduced
6771 * case 5 => content2.apply(args(0).asInstanceOf[Expr[U1]], args(1).asInstanceOf[Expr[U2]]).apply(quotes) // beta reduced
72+ * case 6 => content2.apply(args(0).asInstanceOf[Type[?]], args(1).asInstanceOf[Expr[U1]]).apply(quotes) // beta reduced
6873 * },
6974 * )
7075 * ```
@@ -126,13 +131,36 @@ class PickleQuotes extends MacroTransform {
126131 private val contents = List .newBuilder[Tree ]
127132 override def transform (tree : tpd.Tree )(using Context ): tpd.Tree =
128133 tree match
129- case tree @ Hole (isTerm, _, _ , content, _ ) =>
134+ case tree @ Hole (isTerm, idx, rawArgs , content, tpt ) =>
130135 if ! content.isEmpty then
131136 contents += content
132- val holeType =
133- if isTerm then getTermHoleType(tree.tpe) else getTypeHoleType(tree.tpe)
134- val hole = cpy.Hole (tree)(content = EmptyTree , TypeTree (holeType))
135- if isTerm then Inlined (EmptyTree , Nil , hole).withSpan(tree.span) else hole
137+ if isTerm then // transform into method call `hole[idx, T', Targs](args*)`
138+ val targs = rawArgs.filter(! _.isTerm)
139+ val args = rawArgs.filter(_.isTerm).map { arg =>
140+ def fullyAppliedToDummyArgs (arg : Tree , tpe : Type ): Tree =
141+ tpe match
142+ case tpe : MethodType =>
143+ fullyAppliedToDummyArgs(arg.appliedToArgs(tpe.paramNames.map(_ => tpd.ref(defn.Predef_undefined ))), tpe.resultType)
144+ case tpe : PolyType =>
145+ fullyAppliedToDummyArgs(arg.appliedToTypes(tpe.paramInfos.map(_.loBound)), tpe.resultType)
146+ case _ => arg
147+ fullyAppliedToDummyArgs(arg, arg.tpe.widenTermRefExpr)
148+ }
149+ val holeType = getTermHoleType(tree.tpe)
150+ val typeArgs = tpd.hkNestedPairsTypeTree(targs).tpe
151+ val holeTypeArgs = List (ConstantType (Constant (idx)), holeType, typeArgs)
152+ val newHole =
153+ ref(defn.QuoteUnpickler_exprHole )
154+ .appliedToTypes(holeTypeArgs)
155+ .appliedToVarargs(args, TypeTree (defn.AnyType ))
156+ .withSpan(tree.span)
157+ Inlined (EmptyTree , Nil , newHole).withSpan(tree.span)
158+ else // transform into type `hole[idx, T']`
159+ assert(rawArgs.isEmpty)
160+ val holeType = getTypeHoleType(tree.tpe)
161+ val holeTypeArgs = List (ConstantType (Constant (idx)), holeType)
162+ TypeTree (AppliedType (defn.QuoteUnpickler_typeHole .typeRef, holeTypeArgs))
163+ .withSpan(tree.span)
136164 case tree : DefTree =>
137165 val newAnnotations = tree.symbol.annotations.mapconserve { annot =>
138166 annot.derivedAnnotation(transform(annot.tree)(using ctx.withOwner(tree.symbol)))
0 commit comments