-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Define @__FUNCTION__
as an alias to var"#self#"
#58909
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?
Conversation
Referencing the discussion about implementations of this in #6733. |
This should also be added to the docs. I'm surprised this isn't caught by CI. |
Thanks; done |
tagging triage to talk about an expansion of the public API |
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.
SGTM
Could you add some tests for kwarg handling too, since those functions are tricky (even if you have to make them test_broken for now)
Co-authored-by: Jameson Nash <[email protected]>
Thanks; added |
@@ -131,6 +131,11 @@ end | |||
test_do_block() | |||
end | |||
|
|||
@testset "Compatibility with kwargs" begin | |||
foo(; n) = n <= 1 ? 1 : n * (@__FUNCTION__)(; n = n - 1) | |||
@test foo(n = 5) == 120 |
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.
It looks like this is getting a closure captured #self#
value copy instead of using the argument. It is hard to distinguish, since they are the identical value, but it appears to result in the self value getting passed to the inner kwarg function twice (and so it might appear as more of an issue once the other related function is merged).
julia> methods(ans)[1]
var"#f#5"(y, ::typeof(f))
@ Main REPL[8]:1
julia> Base.method_argnames(ans)
3-element Vector{Symbol}:
Symbol("#f#5")
:y
Symbol("") # expected `#self#` 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.
What is the first ans
there?
With a build on #58913 I see this:
julia> mutable struct Bar
x::Int
end
julia> b = Bar(1)
Bar(1)
julia> (::Bar)(; n=2) = @__FUNCTION__
julia> b === Bar(1)
false
julia> b === b()
true
julia> methods(b)[1]
(::Bar)(; n)
@ Main REPL[21]:1
julia> Base.method_argnames(ans)
1-element Vector{Symbol}:
Symbol("#self#")
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.
Oh from this I guess?
julia> @code_warntype foo(n=3)
MethodInstance for Core.kwcall(::@NamedTuple{n::Int64}, ::typeof(foo))
from kwcall(::NamedTuple, ::typeof(foo)) @ Main REPL[26]:1
Arguments
_::Core.Const(Core.kwcall)
@_2::@NamedTuple{n::Int64}
@_3::Core.Const(Main.foo)
Locals
@_4::Int64
n::Int64
Body::Int64
1 ─ Core.NewvarNode(:(@_4))
│ %2 = Core.isdefined(@_2, :n)::Core.Const(true)
└── goto #3 if not %2
2 ─ (@_4 = Core.getfield(@_2, :n))
└── goto #4
3 ─ Core.Const(:(Core.UndefKeywordError(:n)))
└── Core.Const(:(@_4 = Core.throw(%6)))
4 ┄ %8 = @_4::Int64
│ (n = %8)
│ %10 = Base.keys(@_2)::Core.Const((:n,))
│ %11 = (:n,)::Core.Const((:n,))
│ %12 = Base.diff_names(%10, %11)::Core.Const(())
│ %13 = Base.isempty(%12)::Core.Const(true)
└── goto #6 if not %13
5 ─ goto #7
6 ─ Core.Const(:(Base.kwerr(@_2, @_3)))
7 ┄ %17 = Main.:(var"#foo#13")::Core.Const(Main.var"#foo#13")
│ %18 = n::Int64
│ %19 = (%17)(%18, @_3)::Int64
└── return %19
julia> methods(var"#foo#13")
# 1 method for generic function "#foo#13" from Main:
[1] var"#foo#13"(n, ::typeof(foo))
@ REPL[26]:1
julia> Base.method_argnames(ans[1])
3-element Vector{Symbol}:
Symbol("#foo#13")
:n
Symbol("")
x-ref #58940 which defines |
Just as
@__MODULE__
refers to the enclosing module object, the internal variablevar"#self#"
can be used to refer to the enclosing function object.This PR creates an alias
@__FUNCTION__
for this variable to match the naming conventions of existing reflection macros (@__MODULE__
,@__FILE__
, etc.).Fixes #58908 Fixes #6733