-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Avoid leak of internal implementation in tasty.Reflection #9613
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
Conversation
ba5d236 to
b6d0c5b
Compare
|
Note that this change does not affect the |
liufengyun
left a comment
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
| */ | ||
| 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.TermThere 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.
| 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.
|
|
||
| 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
| /** 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
liufengyun
left a comment
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 leakCompilerInterfaceas a self typeReflectionandComplerInterfaceComplerInterface.leakto allow access to internals within the library