-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix #5107: disallow block as Apply.fun #5190
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
Conversation
This should make part of https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/Splitter.scala unnecessary (it could be simplified even more if you also disallowed If trees as Apply.fun). |
else readaptSimplified(tpd.Apply(tree, args)) | ||
else tree match { | ||
case tree: Block => | ||
readaptSimplified(tpd.Block(tree.stats, tpd.Apply(tree.expr, args))) |
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 if tree.expr is a block itself? This is handled by https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/Splitter.scala
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.
Just added an assert in tpd.Apply
, it seems this can never happen.
@@ -300,6 +301,12 @@ class TreeChecker extends Phase with SymTransformer { | |||
res | |||
} | |||
|
|||
def checkApplyNonBlock(tree: untpd.Tree)(implicit ctx: Context) = tree match { | |||
case tree: untpd.Apply => assert(!tree.fun.isInstanceOf[untpd.Block]) |
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 is a really lightweight check, so instead of doing in TreeChecker I would just do it in the constructor of Apply.
ta.assignType(untpd.Apply(fn, args), fn, args) | ||
} | ||
|
||
def TypeApply(fn: Tree, args: List[Tree])(implicit ctx: Context): TypeApply = | ||
ta.assignType(untpd.TypeApply(fn, args), fn, args) |
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.
You could try to do the same for TypeApply.
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.
Yes, we could do that. I'm wondering how if/else
could possibly appear in fun
. But it is always good to have these invariants if they don't incur much performance cost.
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.
You will probably not be able to. You could add the assertion to make sure.
8b60d82
to
34711c2
Compare
test performance please |
performance test scheduled: 1 job(s) in queue, 0 running. |
Performance test finished successfully: Visit http://dotty-bench.epfl.ch/5190/ to see the changes. Benchmarks is based on merging with master (2b73f9d) |
test performance please |
performance test scheduled: 4 job(s) in queue, 1 running. |
Performance test finished successfully: Visit http://dotty-bench.epfl.ch/5190/ to see the changes. Benchmarks is based on merging with master (e4735d2) |
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
ta.assignType(untpd.Apply(fn, args), fn, args) | ||
} | ||
|
||
def TypeApply(fn: Tree, args: List[Tree])(implicit ctx: Context): TypeApply = | ||
ta.assignType(untpd.TypeApply(fn, args), fn, args) |
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.
You will probably not be able to. You could add the assertion to make sure.
@@ -69,8 +69,7 @@ class Compiler { | |||
new ExplicitOuter, // Add accessors to outer classes from nested ones. | |||
new ExplicitSelf, // Make references to non-trivial self types explicit as casts | |||
new StringInterpolatorOpt, // Optimizes raw and s string interpolators by rewriting them to string concatentations | |||
new CrossCastAnd, // Normalize selections involving intersection types. | |||
new Splitter) :: // Expand selections involving union types into conditionals |
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 splitter source file was nod removed
@@ -40,8 +40,11 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { | |||
def Super(qual: Tree, mixName: TypeName, inConstrCall: Boolean, mixinClass: Symbol = NoSymbol)(implicit ctx: Context): Super = | |||
Super(qual, if (mixName.isEmpty) untpd.EmptyTypeIdent else untpd.Ident(mixName), inConstrCall, mixinClass) | |||
|
|||
def Apply(fn: Tree, args: List[Tree])(implicit ctx: Context): Apply = | |||
def Apply(fn: Tree, args: List[Tree])(implicit ctx: Context): Apply = { | |||
assert(!fn.isInstanceOf[Block]) |
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.
Just a suggestion, but you could be even more radical and assert what fn can be instead of what it cannot be, is assert(fn.isInstanceOf[RefTree] || fn.isInstanceOf[GenericApply])
enough ?
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 for TypeApply
.
5994cca
to
28c2cba
Compare
Thanks @nicolasstucki @smarter . I just updated the PR, could you have a look again? |
|
||
def TypeApply(fn: Tree, args: List[Tree])(implicit ctx: Context): TypeApply = | ||
def TypeApply(fn: Tree, args: List[Tree])(implicit ctx: Context): TypeApply = { | ||
assert(fn.isInstanceOf[RefTree] || fn.isInstanceOf[GenericApply[_]]) |
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.
Can we have nested TypeApply
? Should we check fn.isInstanceOf[Apply[_]]
instead of fn.isInstanceOf[GenericApply[_]]
?
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.
With named type arguments yes I think so foo[A=Int][String]
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.
... also with curried type lambdas.
@@ -17,7 +17,7 @@ import vulpix.TestConfiguration | |||
class PatmatExhaustivityTest { | |||
val testsDir = "tests/patmat" | |||
// stop-after: patmatexhaust-huge.scala crash compiler |
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.
Does it still crash the compiler with the new labelled blocks ?
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.
Just tried locally, it works now.
Edit: CI not happy, reverted.
863c058
to
756c7ea
Compare
Fix #5107: disallow block as Apply.fun