Skip to content

Commit 8f730e1

Browse files
committed
Add missing apply constructors for Refined And TypeProjection TypeTrees
1 parent ca400bd commit 8f730e1

File tree

8 files changed

+80
-3
lines changed

8 files changed

+80
-3
lines changed

compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,8 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
12441244
end TypeProjectionTypeTest
12451245

12461246
object TypeProjection extends TypeProjectionModule:
1247+
def apply(qualifier: TypeTree, name: String): TypeProjection =
1248+
withDefaultPos(tpd.Select(qualifier, name.toTypeName))
12471249
def copy(original: Tree)(qualifier: TypeTree, name: String): TypeProjection =
12481250
tpd.cpy.Select(original)(qualifier, name.toTypeName)
12491251
def unapply(x: TypeProjection): (TypeTree, String) =
@@ -1289,6 +1291,9 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
12891291
end RefinedTypeTest
12901292

12911293
object Refined extends RefinedModule:
1294+
def apply(tpt: TypeTree, refinements: List[Definition], refineCls: Symbol): Refined = // Symbol of the class being refined, according to which the refinements are typed
1295+
assert(refineCls.isClass, "refineCls must be a class/trait/object")
1296+
withDefaultPos(tpd.RefinedTypeTree(tpt, refinements, refineCls.asClass).asInstanceOf[tpd.RefinedTypeTree])
12921297
def copy(original: Tree)(tpt: TypeTree, refinements: List[Definition]): Refined =
12931298
tpd.cpy.RefinedTypeTree(original)(tpt, refinements)
12941299
def unapply(x: Refined): (TypeTree, List[Definition]) =

library/src/scala/quoted/Quotes.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1969,6 +1969,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
19691969

19701970
/** Methods of the module object `val TypeProjection` */
19711971
trait TypeProjectionModule { this: TypeProjection.type =>
1972+
def apply(qualifier: TypeTree, name: String): TypeProjection
19721973
def copy(original: Tree)(qualifier: TypeTree, name: String): TypeProjection
19731974
def unapply(x: TypeProjection): (TypeTree, String)
19741975
}
@@ -2021,6 +2022,13 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
20212022

20222023
/** Methods of the module object `val Refined` */
20232024
trait RefinedModule { this: Refined.type =>
2025+
/** Creates and types a Refined AST node.
2026+
* @param tpt - parent type being refined
2027+
* @param refinements - List of definitions represesenting refinements
2028+
* @param refineCls - symbol of the class of which the refinement definitions originally come from
2029+
* @return
2030+
*/
2031+
def apply(tpt: TypeTree, refinements: List[Definition], refineCls: Symbol): Refined
20242032
def copy(original: Tree)(tpt: TypeTree, refinements: List[Definition]): Refined
20252033
def unapply(x: Refined): (TypeTree, List[Definition])
20262034
}

project/MiMaFilters.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ object MiMaFilters {
1717

1818
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.Conversion.underlying"),
1919
ProblemFilters.exclude[MissingClassProblem]("scala.Conversion$"),
20-
ProblemFilters.exclude[MissingClassProblem]("scala.annotation.internal.RuntimeChecked"),
20+
ProblemFilters.exclude[MissingClassProblem]("scala.annotation.internal.RuntimeChecked"),
2121
ProblemFilters.exclude[MissingClassProblem]("scala.annotation.stableNull"),
2222

2323
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.NamedTuple.namedTupleOrdering"),
@@ -138,6 +138,8 @@ object MiMaFilters {
138138
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#MethodTypeMethods.isContextual"),
139139
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#ImplicitsModule.searchIgnoring"),
140140
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#ValDefModule.let"),
141+
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#RefinedModule.apply"),
142+
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#TypeProjectionModule.apply"),
141143
// Change `experimental` annotation to a final class
142144
ProblemFilters.exclude[FinalClassProblem]("scala.annotation.experimental"),
143145
),

tests/neg-macros/i23008.check

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
| Exception occurred while executing macro expansion.
66
| java.lang.IllegalArgumentException: requirement failed: value of StringConstant cannot be `null`
77
| at scala.Predef$.require(Predef.scala:337)
8-
| at scala.quoted.runtime.impl.QuotesImpl$reflect$StringConstant$.apply(QuotesImpl.scala:2540)
9-
| at scala.quoted.runtime.impl.QuotesImpl$reflect$StringConstant$.apply(QuotesImpl.scala:2539)
8+
| at scala.quoted.runtime.impl.QuotesImpl$reflect$StringConstant$.apply(QuotesImpl.scala:2545)
9+
| at scala.quoted.runtime.impl.QuotesImpl$reflect$StringConstant$.apply(QuotesImpl.scala:2544)
1010
| at scala.quoted.ToExpr$StringToExpr.apply(ToExpr.scala:82)
1111
| at scala.quoted.ToExpr$StringToExpr.apply(ToExpr.scala:80)
1212
| at scala.quoted.Expr$.apply(Expr.scala:72)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import scala.quoted._
2+
class Test {type test = Int }
3+
object Macro:
4+
inline def inlineCall(): Any = ${impl}
5+
transparent inline def transparentInlineCall(): Any = ${impl}
6+
7+
/* Returns:
8+
* val value: Test#test = 0 : Test#test
9+
* value: Test#test
10+
*/
11+
def impl(using Quotes): Expr[Any] =
12+
import quotes.reflect._
13+
val typeTree = TypeProjection(TypeTree.of[Test], "test")
14+
val typeRepr = TypeRepr.of[Test#test]
15+
val sym = Symbol.newVal(Symbol.spliceOwner, "value", typeRepr, Flags.EmptyFlags, Symbol.noSymbol)
16+
Block(
17+
List(ValDef(sym, Some(Typed(Literal(IntConstant(0)), typeTree)))),
18+
Typed(Ref(sym), typeTree)
19+
).asExpr
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import scala.quoted._
2+
def test() =
3+
Macro.transparentInlineCall()
4+
Macro.inlineCall()
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//> using options -experimental
2+
import scala.quoted._
3+
class Foo { type test1; val test2: List[Any] = List() }
4+
object Macro:
5+
inline def inlineCall(): Any = ${impl}
6+
transparent inline def transparentInlineCall(): Any = ${impl}
7+
8+
def impl(using Quotes): Expr[Any] =
9+
import quotes.reflect._
10+
val tpt = TypeTree.of[Foo]
11+
12+
val typeDefSym = Symbol.newTypeAlias(Symbol.spliceOwner, "test1", Flags.EmptyFlags, TypeRepr.of[Int], Symbol.noSymbol)
13+
val valDefSym = Symbol.newVal(Symbol.spliceOwner, "test2", TypeRepr.of[List[Int]], Flags.EmptyFlags, Symbol.noSymbol)
14+
15+
val defs = List(
16+
TypeDef(typeDefSym),
17+
ValDef(valDefSym, None)
18+
)
19+
val typeTree = Refined(tpt, defs, TypeRepr.of[Foo].typeSymbol)
20+
21+
// A little redundant, but we only want to see if Refined.apply() works,
22+
// so we only replace the type with one we just constructed
23+
val body = '{
24+
new Foo { type test1 = Int; override val test2: List[Int] = List(0) }
25+
}
26+
val blockWithNewTypeTree = body.asTerm match
27+
case Inlined(_, _, Block(cDef : ClassDef, Typed(invocation, _))) =>
28+
Block(cDef, Typed(invocation, typeTree))
29+
30+
blockWithNewTypeTree.asExpr
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//> using options -experimental
2+
3+
import scala.quoted._
4+
def testInt(i: Int) = ()
5+
@main def Test(): Unit =
6+
val withType = Macro.transparentInlineCall()
7+
summon[withType.test1 <:< Int]
8+
withType.test2.map(testInt)
9+
Macro.inlineCall()

0 commit comments

Comments
 (0)