-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Avoid leak of internal implementation in tasty.Reflection #9613
Avoid leak of internal implementation in tasty.Reflection #9613
Conversation
ba5d236
to
b6d0c5b
Compare
Note that this change does not affect the |
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.
LGTM
compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala
Outdated
Show resolved
Hide resolved
compiler/src/dotty/tools/dotc/tastyreflect/ReflectionImpl.scala
Outdated
Show resolved
Hide resolved
@@ -75,7 +75,8 @@ object Expr { | |||
* Otherwise returns `expr`. | |||
*/ | |||
def betaReduce[T](expr: Expr[T])(using qctx: QuoteContext): Expr[T] = | |||
qctx.tasty.internal.betaReduce(expr.unseal) match | |||
val qctx2 = scala.internal.tasty.CompilerInterface.leaked(qctx) |
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.
The name leaked
is not intuitive about what it does? It seems better to use an more informative verb instead.
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.
It is not obvious why we cannot just use qctx
here, as before?
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.
The trick is that the public API of QuoteContext
exposes QuoteContext.tasty
as Reflection
, but we always implement is by mixing in the CompilerInterface
. These methods are not intended to be used directly by the users, so we hide them inside the CompilerInterface
. This interface should only be used within the library.
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.
I renamed it to quoteContextWithCompilerInterface
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.
What about just return an instance of CompilerInterface
? That will make things more clean:
val ci: CompilerInterface = scala.internal.tasty.CompilerInterface(qtx)
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.
That was what I tried.
[error] -- [E007] Type Mismatch Error: /Users/nicolasstucki/GitHub/dotty2/library/src-bootstrapped/scala/quoted/Expr.scala:80:18
[error] val ci = CompilerInterface(qctx)
[error] 80 | ci.betaReduce(expr.unseal) match
[error] | ^^^^^^^^^^^
[error] | Found: qctx.tasty.Term
[error] | Required: ci.Term
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.
Might be a bug in TypeComparer? I'll try to minimize.
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.
We can improve that that later. This change only affects internal implementation.
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.
@liufengyun Dotty currently doesn't support reasoning about refining singletons, which feels like a big oversight: lampepfl/dotty-feature-requests#89
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.
Thanks for the pointer @LPTK . Yes, indeed it is. We also lose the reasoning about paths for class parameters. I agree that a systematic approach is needed to support reasoning about path equality in path-dependent types.
@@ -19,12 +19,12 @@ object Lambda { | |||
import qctx.tasty._ | |||
val argTypes = functionType.unseal.tpe match | |||
case AppliedType(_, functionArguments) => functionArguments.init.asInstanceOf[List[Type]] | |||
qctx.tasty.internal.lambdaExtractor(expr.unseal, argTypes).map { fn => | |||
val qctx2 = scala.internal.tasty.CompilerInterface.leaked(qctx) |
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.
Same question as above: can we just use qctx
?
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.
OK, agreed.
@@ -19,7 +19,7 @@ import scala.quoted._ | |||
} | |||
|
|||
def unseal(using qctx: QuoteContext): qctx.tasty.Term = | |||
if (qctx.tasty.internal.compilerId != scopeId) | |||
if (scala.internal.tasty.CompilerInterface.leaked(qctx).tasty.compilerId != scopeId) |
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.
Same question as above
@@ -14,7 +14,7 @@ final class Type[Tree](val typeTree: Tree, val scopeId: Int) extends scala.quote | |||
|
|||
/** View this expression `quoted.Type[T]` as a `TypeTree` */ | |||
def unseal(using qctx: QuoteContext): qctx.tasty.TypeTree = | |||
if (qctx.tasty.internal.compilerId != scopeId) | |||
if (scala.internal.tasty.CompilerInterface.leaked(qctx).tasty.compilerId != scopeId) |
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.
Same question as above
* Remove `Reflection.internal`: the source of the leak * Add `CompilerInterface` as a self type * Add common type abstraction for `Reflection` and `ComplerInterface` * Add `ComplerInterface.leak` to allow access to internals within the library
b6d0c5b
to
a2d3821
Compare
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.
Otherwise, LGTM
Reflection.internal
: the source of the leakCompilerInterface
as a self typeReflection
andComplerInterface
ComplerInterface.leak
to allow access to internals within the library