-
-
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
effects: add reflection utility for the new effect analysis #44785
Conversation
d95188a
to
fbfec6c
Compare
I'd like to merge #44786 first before merging this PR. |
082c123
to
d744e44
Compare
Note: I will add |
d744e44
to
5146e35
Compare
Ok, I'd like to move this forward quickly if possible, and let me work on |
This commit adds new reflection utility named `Base.infer_effects` that works in the same way as `Base.return_types` but returns inferred effects instead. It would be helpful to test that certain method call has an expected effects. For example, we can now remove `Base.@pure` annotation from the definition of `BroadcastStyle(a::A, b::B) where {A<:AbstractArrayStyle{M},B<:AbstractArrayStyle{N}} where {M,N}` and checks it's still eligible for concrete evaluation like this (see <#44776 (comment)> for the context): ```julia julia> import Base.Broadcast: AbstractArrayStyle, DefaultArrayStyle, Unknown julia> function BroadcastStyle(a::A, b::B) where {A<:AbstractArrayStyle{M},B<:AbstractArrayStyle{N}} where {M,N} if Base.typename(A) === Base.typename(B) return A(Val(max(M, N))) end return Unknown() end BroadcastStyle (generic function with 1 method) julia> # test that the above definition is eligible for concrete evaluation @test Base.infer_effects(BroadcastStyle, (DefaultArrayStyle{1},DefaultArrayStyle{2},)) |> Core.Compiler.is_total_or_error Test Passed ```
5146e35
to
51f4632
Compare
base/reflection.jl
Outdated
if isempty(matches) | ||
# although this call is known to throw MethodError (thus `nothrow=ALWAYS_TRUE`), | ||
# still mark it `TRISTATE_UNKNOWN` just in order to be consistent with a result | ||
# derived by the effect analysis, which can't prove guaranteed throwness at this moment | ||
return Core.Compiler.Effects(effects; nothrow=Core.Compiler.TRISTATE_UNKNOWN) |
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 think it's not too clear what effects we should return for this case.
For now, I made the result equivalent to the following case:
julia> function f_no_methods end
f_no_methods (generic function with 0 methods)
julia> Base.infer_effects() do
throw(MethodError(f_no_methods, ()))
end
(+c,+e,?n,+t)
Co-authored-by: Takafumi Arakaki <[email protected]>
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 can't review all the details but it LGTM! The API is what I wanted.
This commit adds new reflection utility named `Base.infer_effects` that works in the same way as `Base.return_types` but returns inferred effects instead. It would be helpful to test that certain method call has an expected effects. For example, we can now remove `Base.@pure` annotation from the definition of `BroadcastStyle(a::A, b::B) where {A<:AbstractArrayStyle{M},B<:AbstractArrayStyle{N}} where {M,N}` and checks it's still eligible for concrete evaluation like this (see <#44776 (comment)> for the context): ```julia julia> import Base.Broadcast: AbstractArrayStyle, DefaultArrayStyle, Unknown julia> function BroadcastStyle(a::A, b::B) where {A<:AbstractArrayStyle{M},B<:AbstractArrayStyle{N}} where {M,N} if Base.typename(A) === Base.typename(B) return A(Val(max(M, N))) end return Unknown() end BroadcastStyle (generic function with 1 method) julia> # test that the above definition is eligible for concrete evaluation @test Base.infer_effects(BroadcastStyle, (DefaultArrayStyle{1},DefaultArrayStyle{2},)) |> Core.Compiler.is_total_or_error Test Passed ``` Co-authored-by: Takafumi Arakaki <[email protected]>
This commit adds new reflection utility named `Base.infer_effects` that works in the same way as `Base.return_types` but returns inferred effects instead. It would be helpful to test that certain method call has an expected effects. For example, we can now remove `Base.@pure` annotation from the definition of `BroadcastStyle(a::A, b::B) where {A<:AbstractArrayStyle{M},B<:AbstractArrayStyle{N}} where {M,N}` and checks it's still eligible for concrete evaluation like this (see <#44776 (comment)> for the context): ```julia julia> import Base.Broadcast: AbstractArrayStyle, DefaultArrayStyle, Unknown julia> function BroadcastStyle(a::A, b::B) where {A<:AbstractArrayStyle{M},B<:AbstractArrayStyle{N}} where {M,N} if Base.typename(A) === Base.typename(B) return A(Val(max(M, N))) end return Unknown() end BroadcastStyle (generic function with 1 method) julia> # test that the above definition is eligible for concrete evaluation @test Base.infer_effects(BroadcastStyle, (DefaultArrayStyle{1},DefaultArrayStyle{2},)) |> Core.Compiler.is_total_or_error Test Passed ``` Co-authored-by: Takafumi Arakaki <[email protected]>
This commit adds new reflection utility named
Base.infer_effects
thatworks in the same way as
Base.return_types
but returns inferred effectsinstead. It would be helpful to test that certain method call has an
expected effects.
For example, we can now remove
Base.@pure
annotation from the definition ofBroadcastStyle(a::A, b::B) where {A<:AbstractArrayStyle{M},B<:AbstractArrayStyle{N}} where {M,N}
and checks it's still eligible for concrete evaluation like this
(see #44776 (comment) for the context):