-
-
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 some macro expansion scope bugs #22985
Conversation
splice!(Base.LOAD_CACHE_PATH, 1) | ||
@test isdefined(Main, :f22101) | ||
@test f22101()::Vector{Int} == collect(1:10) | ||
@eval workspace() using Test22101 |
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 looks strange, what is this doing?
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.
running eval in a new workspace
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.
is that any different than
workspace()
@eval Main using Test22101
?
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.
Core.Main
, and no difference, those would name the same module
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.
Is this the only reason you made workspace()
return the module or is there some other motivating reason for that?
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.
If the test passes, they were the same. If not, it may or may not be a bug.
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.
How could it not pass if it is returning Core.Main
? This change seems unnecessary and unrelated.
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.
As I said, if it passes, they might be the equivalent. If not, it might be a bug.
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've made it return Core.Main - if functions suddenly returned something other than what they say they do, we'd have bigger problems?
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.
Perhaps. But note that these expressions are run in different scopes.
@test docstrings_equal(Docs.@repl(DocsTest.t(0, 0)), t) | ||
@test docstrings_equal(Docs.@repl(DocsTest.t(::Int, ::Int)), t) | ||
@test docstrings_equal(Docs.@repl((@__MODULE__).DocsTest.t(0, 0)), t) | ||
@test docstrings_equal(Docs.@repl((@__MODULE__).DocsTest.t(::Int, ::Int)), t) |
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.
Is this change actually necessary? I'm worried that resolution of identifiers in macro arguments could depend on the number of layers of macros involved.
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. Previously we did _apply(macrocall, map(resolvescope, args...)...)
, but only if the macro was called recursively. Now this does resolvescope(_apply(macrocall, args...))
.
This also means that now I'm essentially just deferring scope resolution until the aptly named resolve-scopes
function, instead of having a second implementation of it in this file.
The downside of this is that it means macro authors may need to fix their usages of recursive macros to reflect the correct scope rules here.
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 behavior I think we want is for DocsTest
to resolve to the call environment no matter what the macros do (unless they very specifically mangle the identifier to something else).
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.
Edit: this turns out to be needed because @repl
explicitly looks up everything in Main
; that confused me.
It's the inverse, but not actually the reverse (or something like that. yeah, it's confusing). IIUC, with this fix, implementing that PR simply means that we need to automatically wrap all arguments to macros in |
If I remember, one thing I liked about #10940 is that it basically leaves macro arguments as they are now, and instead wraps symbols inside quoted code in macros with |
If my recollection of my rebase attempt serves though, it actually couldn't leave them alone. It sometimes mangled them into Calling this "the inverse" was perhaps too tongue-in-cheek, since I meant it was approaching the fix to a particular bug from the other direction (a bug that the implementation in #10940 sadly doesn't actually end up fixing completely, I think it just reduced it in severity). But anyways, wrapping quoting / interpolation instead of wrapping the arguments is another possible avenue to implementing #10940 that becomes much easier and more correct with this PR. In this PR, I called that operation |
This change is breaking everything and needs to be reverted or fixed ASAP. |
This fixes macro hygiene for cases where a macro returns a call to another macro. It's actually a bit like doing the inverse of #10940.