-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
WIP: Turn Expr(:method) into a builtin
#60099
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1454,6 +1454,46 @@ function deserialize_expr(s::AbstractSerializer, len) | |
| resolve_ref_immediately(s, e) | ||
| e.head = deserialize(s)::Symbol | ||
| e.args = Any[ deserialize(s) for i = 1:len ] | ||
|
|
||
| # Rewrite old :method expressions to define_method calls | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems unlikely we should encounter or support this, since pre-lowered top level code is a pretty buggy concept even in a single session
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have a specific test for this case, so I added the compat. We can remove the test if course
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Weird, but I guess harmless probably |
||
| if e.head === :method | ||
| mod = current_module[] | ||
| if mod === nothing | ||
| # No current module context, keep the :method expression and hope for the best | ||
| # This shouldn't happen in practice for deserialization of top-level code | ||
| return e | ||
| end | ||
|
|
||
| if len == 1 | ||
| # Short form: (:method name) → (call Core.define_method module (inert name)) | ||
| name = e.args[1] | ||
| if name isa GlobalRef | ||
| # Extract module and name from GlobalRef | ||
| mod_ref = name.mod | ||
| sym = name.name | ||
| e = Expr(:call, GlobalRef(Core, :define_method), mod_ref, QuoteNode(sym)) | ||
| else | ||
| # Simple symbol - use the current module | ||
| e = Expr(:call, GlobalRef(Core, :define_method), mod, QuoteNode(name)) | ||
| end | ||
| elseif len == 3 | ||
| # Long form: (:method name_or_mt sigtype code) → (call Core.define_method module name_or_mt sigtype code) | ||
| name_or_mt = e.args[1] | ||
| sigtype = e.args[2] | ||
| code = e.args[3] | ||
| if name_or_mt isa Symbol | ||
| name_or_mt = QuoteNode(name_or_mt) | ||
| e = Expr(:call, GlobalRef(Core, :define_method), mod, name_or_mt, sigtype, code) | ||
| elseif name_or_mt isa GlobalRef | ||
| mod_ref = name_or_mt.mod | ||
| sym = name_or_mt.name | ||
| e = Expr(:call, GlobalRef(Core, :define_method), mod_ref, QuoteNode(sym), sigtype, code) | ||
| else | ||
| # name_or_mt is already something else (like false or a method table) | ||
| e = Expr(:call, GlobalRef(Core, :define_method), mod, name_or_mt, sigtype, code) | ||
| end | ||
| end | ||
| end | ||
| e | ||
| end | ||
|
|
||
|
|
||
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 this need a check that the module is "open" or does it already have that internally?
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'll double check, but you may be correct that we were relying on the eval check before.