-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix #9751: Fix Inline purity checks #9753
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
5f8f19e
to
d97fc04
Compare
d97fc04
to
bf64e9d
Compare
bf64e9d
to
9b3d80d
Compare
We wrongly identified most inline references as pure as they are effectively erased. Only erased terms are always pure. Most of the purity of inline references follows from the normal purity rules except for inline parameters. These parameters lose their binding when inlined and no purity guaranty can be ensured from the reference.
9b3d80d
to
c159361
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
&& !ctx.isAfterTyper | ||
&& !tree.isInstanceOf[Inlined] | ||
&& isPureExpr(tree) | ||
&& !isSelfOrSuperConstrCall(tree) |
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.
tree.isInstanceOf[Inlined]
: can an inlined tree be pure? What about handle inlined trees in isPureExpr
?
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 Inlined trees can be pure which is correctly identified in isPureExpr. Here we special case a
Inlined calls that inserted a pure expression in a statement position as these are only pure due to other constraints that may change. For example, the assert can take a reference to an Inlined true value which converts it in a no-op and we do not want to warn that this is a pure expression in statement position.
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 explanation. It might be good to add a short comment after the line.
@@ -47,7 +47,7 @@ abstract class TransformByNameApply extends MiniPhase { thisPhase: DenotTransfor | |||
ref(defn.cbnArg).appliedToType(argType).appliedTo(arg).withSpan(arg.span) | |||
arg match { | |||
case Apply(Select(qual, nme.apply), Nil) | |||
if qual.tpe.derivesFrom(defn.FunctionClass(0)) && isPureExpr(qual) => | |||
if qual.tpe.derivesFrom(defn.FunctionClass(0)) && (isPureExpr(qual) || qual.symbol.isAllOf(Inline | Param)) => |
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 matter? If I were correct, the body of inlined methods is never executed, thus only the TASTY matters.
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.
In theory that seems to be the case. But I caught one that came for the DottyPredef.assert
when compiling dotty itself. It might be a re-bootstrapping issue.
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 see. It could be some invariants after the typer -- and it's always good to do so.
We wrongly identified most inline references as pure as they are effectively erased.
Only erased terms are always pure.
Most of the purity of inline references follows from the normal purity rules except for inline parameters.
These parameters lose their binding when inlined and no purity guaranty can be ensured from the reference.