-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix QuotesCache caching quoted symbol definitions with incorrect owners #20492
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -164,7 +164,9 @@ trait RunnerOrchestration { | |
*/ | ||
private def createProcess: Process = { | ||
val url = classOf[ChildJVMMain].getProtectionDomain.getCodeSource.getLocation | ||
val cp = Paths.get(url.toURI).toString + JFile.pathSeparator + Properties.scalaLibrary | ||
val cp = Paths.get(url.toURI).toString + | ||
JFile.pathSeparator + Properties.scalaLibrary + | ||
JFile.pathSeparator + Properties.dottyLibrary | ||
Comment on lines
-167
to
+169
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had to add the dottyLibrary to runtime of the test here, because otherwise the run_staging tests would fail on windows (as it would be fail trying to access |
||
val javaBin = Paths.get(sys.props("java.home"), "bin", "java").toString | ||
new ProcessBuilder(javaBin, "-Dfile.encoding=UTF-8", "-Duser.language=en", "-Duser.country=US", "-Xmx1g", "-cp", cp, "dotty.tools.vulpix.ChildJVMMain") | ||
.redirectErrorStream(true) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import scala.annotation.experimental | ||
import scala.quoted.* | ||
import scala.annotation.tailrec | ||
|
||
object FlatMap { | ||
@experimental inline def derived[F[_]]: FlatMap[F] = MacroFlatMap.derive | ||
} | ||
trait FlatMap[F[_]]{ | ||
def tailRecM[A, B](a: A)(f: A => F[Either[A, B]]): F[B] | ||
} | ||
|
||
@experimental | ||
object MacroFlatMap: | ||
|
||
inline def derive[F[_]]: FlatMap[F] = ${ flatMap } | ||
|
||
def flatMap[F[_]: Type](using Quotes): Expr[FlatMap[F]] = '{ | ||
new FlatMap[F]: | ||
def tailRecM[A, B](a: A)(f: A => F[Either[A, B]]): F[B] = | ||
${ deriveTailRecM('{ a }, '{ f }) } | ||
} | ||
|
||
def deriveTailRecM[F[_]: Type, A: Type, B: Type]( | ||
a: Expr[A], | ||
f: Expr[A => F[Either[A, B]]] | ||
)(using q: Quotes): Expr[F[B]] = | ||
import quotes.reflect.* | ||
|
||
val body: PartialFunction[(Symbol, TypeRepr), Term] = { | ||
case (method, tpe) => { | ||
given q2: Quotes = method.asQuotes | ||
'{ | ||
def step(x: A): B = ??? | ||
??? | ||
}.asTerm | ||
} | ||
} | ||
|
||
val term = '{ $f($a) }.asTerm | ||
val name = Symbol.freshName("$anon") | ||
val parents = List(TypeTree.of[Object], TypeTree.of[F[B]]) | ||
|
||
extension (sym: Symbol) def overridableMembers: List[Symbol] = | ||
val member1 = sym.methodMember("abstractEffect")(0) | ||
val member2 = sym.methodMember("concreteEffect")(0) | ||
def meth(member: Symbol) = Symbol.newMethod(sym, member.name, This(sym).tpe.memberType(member), Flags.Override, Symbol.noSymbol) | ||
List(meth(member1), meth(member2)) | ||
|
||
val cls = Symbol.newClass(Symbol.spliceOwner, name, parents.map(_.tpe), _.overridableMembers, None) | ||
|
||
def transformDef(method: DefDef)(argss: List[List[Tree]]): Option[Term] = | ||
val sym = method.symbol | ||
Some(body.apply((sym, method.returnTpt.tpe))) | ||
|
||
val members = cls.declarations | ||
.filterNot(_.isClassConstructor) | ||
.map: sym => | ||
sym.tree match | ||
case method: DefDef => DefDef(sym, transformDef(method)) | ||
case _ => report.errorAndAbort(s"Not supported: $sym in ${sym.owner}") | ||
|
||
val newCls = New(TypeIdent(cls)).select(cls.primaryConstructor).appliedToNone | ||
Block(ClassDef(cls, parents, members) :: Nil, newCls).asExprOf[F[B]] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import scala.annotation.experimental | ||
|
||
@experimental | ||
object autoFlatMapTests: | ||
trait TestAlgebra[T] derives FlatMap: | ||
def abstractEffect(a: String): T | ||
def concreteEffect(a: String): T = abstractEffect(a + " concreteEffect") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part was inspired by 94f069e, but instead of looking for any symbol in the unpicked tree to decide whether to cache/uncache, we decide whether to cache with or without the context owner. This keeps the previous performance improvements while keeping the owners unpicked symbols always correct