-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Fix functionloc #35138
Fix functionloc #35138
Conversation
cfcfc5d
to
87a4382
Compare
Ah, interesting. |
Ok, the doctests bring up some more serious ways that this approach can lead to unfortunate results:
In general I like this approach on the runtime side but it seems too fragile to use with confidence without parser support.
Absolutely agreed! Let's do it this way. |
73aba0b
to
e79f14b
Compare
LGTM, just has the inevitable detailed test errors. |
Thanks for taking another look, I'll sort out those test issues, then merge. I think this is likely to incidentally break the occasional package even though it's technically-not-API-breaking. Is there any way to flag this kind of thing so users can easily understand what has changed and how to fix their code? Applying the |
; which should be removed from the body. | ||
(let loop ((stmts body)) | ||
(if (eq? functionloc (cadr stmts)) | ||
(set-cdr! stmts (cddr stmts)) |
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 felt like using set-cdr!
here wasn't great. Is there a more natural idiomatic way to do this?
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.
(Taking into account that we'll need to return both the line number and the body if this is pure.)
Ok, so this should be very close. There's one remaining problem: code coverage has changed because it now includes the line of the function definition. It turns out this is because the line from the Line 5070 in f4c3f1d
Line 5910 in f4c3f1d
I'm not sure what the desired outcome would be here — is it useful to consider the function definition line as code which should be included in the coverage output, or not? There's also other uses of |
To record a discussion about coverage with Jeff and Keno - the consensus was that we shouldn't visit the function definition line (unless it contains executable code), so some small adjustments to coverage codegen will be needed here. |
Some code archeology on the special case handling of
I think the code which the |
cef41c1
to
21e9ead
Compare
This comes in three pieces: * In the parser, put an addition LineNumberNode at the top of each function body to track the line of the function definition * In lowering, remove this LineNumberNode from the body and add it as the last parameter to method signature in `Expr(:method, name, sig, body)` * In the runtime, extract the line number node from sig and add it to the jl_method_t. Since the first line is now correctly tracked separately from the body, a special case in coverage codegen was removed. This was required when line numbers were tracked in a different way - see origin of this in the use of `toplineno` in bug #17442 and fix #17470.
21e9ead
to
009b210
Compare
if (info.file == ctx.file && info.line == toplineno && info.is_user_code == mod_is_user_mod) | ||
current_lineinfo.push_back(1); | ||
} | ||
} |
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've removed this coverage stuff for the reasons explained in the commit message: It seems like a workaround for an old bug #17442, and now we have this double-counting workaround which appears to be a workaround-workaround. So I just deleted this. I also found coverageVisitStmt
a bit confusing so I added some comments above, which I hope correctly state what is going on.
…35138) This comes in three pieces: * In the parser, put an additional LineNumberNode at the top of each function body to track the line of the function definition * In lowering, remove this LineNumberNode from the body and add it as the last parameter to method signature in `Expr(:method, name, sig, body)` * In the runtime, extract the line number node from sig and add it to the jl_method_t. Since the first line is now correctly tracked separately from the body, a special case in coverage codegen was removed. This was required when line numbers were tracked in a different way - see origin of this in the use of `toplineno` in bug JuliaLang#17442 and fix JuliaLang#17470.
…35138) This comes in three pieces: * In the parser, put an additional LineNumberNode at the top of each function body to track the line of the function definition * In lowering, remove this LineNumberNode from the body and add it as the last parameter to method signature in `Expr(:method, name, sig, body)` * In the runtime, extract the line number node from sig and add it to the jl_method_t. Since the first line is now correctly tracked separately from the body, a special case in coverage codegen was removed. This was required when line numbers were tracked in a different way - see origin of this in the use of `toplineno` in bug JuliaLang#17442 and fix JuliaLang#17470.
JuliaLang/julia#35138 changed it so that the method's line number is the declaration, not the first line of the body. This also reworks the line-number detection logic on older releases, and it should be more robust.
JuliaLang/julia#35138 changed it so that the method's line number is the declaration, not the first line of the body. This also reworks the line-number detection logic on older releases, and it should be more robust.
…35138) This comes in three pieces: * In the parser, put an additional LineNumberNode at the top of each function body to track the line of the function definition * In lowering, remove this LineNumberNode from the body and add it as the last parameter to method signature in `Expr(:method, name, sig, body)` * In the runtime, extract the line number node from sig and add it to the jl_method_t. Since the first line is now correctly tracked separately from the body, a special case in coverage codegen was removed. This was required when line numbers were tracked in a different way - see origin of this in the use of `toplineno` in bug JuliaLang#17442 and fix JuliaLang#17470.
This comes in three pieces: * In the parser, put an additional LineNumberNode at the top of each function body to track the line of the function definition * In lowering, remove this LineNumberNode from the body and add it as the last parameter to method signature in `Expr(:method, name, sig, body)` * In the runtime, extract the line number node from sig and add it to the jl_method_t. Since the first line is now correctly tracked separately from the body, a special case in coverage codegen was removed. This was required when line numbers were tracked in a different way - see origin of this in the use of `toplineno` in bug #17442 and fix #17470.
This is a WIP of one way to fix #34820 — I'm not sure it's the best approach, but throwing it up there for discussion.
The approach taken here is to add a line number node to the method
signature
argument inExpr(:method, name, signature, body)
after the signature argument types and names. I tried several options involving lowering ofExpr(:method)
and it turns out that this is quite minimally invasive way to do this. I also think it makes some sense: the method declaration is more a property of the method than it is relevant to the bodyCodeInfo
.However, there's one downside I know about, which is that functions defined in expressions (rather than as statements) can have a line number which is incorrect. In particular, the following test breaks:
Presumably this could be fixed by changing parsing of functions which occur inside expressions to be enclosed in an
Expr(:block)
. Perhaps that's a reasonable way to go?TODO