Skip to content

Commit

Permalink
make default types work for any function with one method
Browse files Browse the repository at this point in the history
  • Loading branch information
aviatesk committed Oct 5, 2021
1 parent 0576c25 commit 0f2d0e2
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 14 deletions.
18 changes: 15 additions & 3 deletions base/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1160,7 +1160,7 @@ additional optimizations, such as inlining, are also applied.
The keyword `debuginfo` controls the amount of code metadata present in the output,
possible options are `:source` or `:none`.
"""
function code_typed(@nospecialize(f), @nospecialize(types=Tuple);
function code_typed(@nospecialize(f), @nospecialize(types=default_tt(f));
optimize=true,
debuginfo::Symbol=:default,
world = get_world_counter(),
Expand All @@ -1181,6 +1181,18 @@ function code_typed(@nospecialize(f), @nospecialize(types=Tuple);
return code_typed_by_type(tt; optimize, debuginfo, world, interp)
end

# returns argument tuple type which is supposed to be used for `code_typed` and its family;
# if there is a single method this functions returns the method argument signature,
# otherwise returns `Tuple` that doesn't match with any signature
function default_tt(@nospecialize(f))
ms = methods(f)
if length(ms) == 1
return tuple_type_tail(only(ms).sig)
else
return Tuple
end
end

"""
code_typed_by_type(types::Type{<:Tuple}; ...)
Expand Down Expand Up @@ -1218,7 +1230,7 @@ function code_typed_by_type(@nospecialize(tt::Type);
return asts
end

function code_typed_opaque_closure(@nospecialize(closure::Core.OpaqueClosure), @nospecialize(types=Tuple{});
function code_typed_opaque_closure(@nospecialize(closure::Core.OpaqueClosure);
optimize=true,
debuginfo::Symbol=:default,
interp = Core.Compiler.NativeInterpreter(closure.world))
Expand All @@ -1232,7 +1244,7 @@ function code_typed_opaque_closure(@nospecialize(closure::Core.OpaqueClosure), @
end
end

function return_types(@nospecialize(f), @nospecialize(types=Tuple), interp=Core.Compiler.NativeInterpreter())
function return_types(@nospecialize(f), @nospecialize(types=default_tt(f)), interp=Core.Compiler.NativeInterpreter())
ccall(:jl_is_in_pure_context, Bool, ()) && error("code reflection cannot be used from generated functions")
if isa(f, Core.Builtin)
throw(ArgumentError("argument is not a generic function"))
Expand Down
12 changes: 6 additions & 6 deletions stdlib/InteractiveUtils/src/codeview.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Keyword argument `debuginfo` may be one of `:source` or `:none` (default), to sp
See [`@code_warntype`](@ref man-code-warntype) for more information.
"""
function code_warntype(io::IO, @nospecialize(f), @nospecialize(t);
function code_warntype(io::IO, @nospecialize(f), @nospecialize(t=Base.default_tt(f));
debuginfo::Symbol=:default, optimize::Bool=false, kwargs...)
debuginfo = Base.IRShow.debuginfo(debuginfo)
lineprinter = Base.IRShow.__debuginfo[debuginfo]
Expand Down Expand Up @@ -134,7 +134,7 @@ function code_warntype(io::IO, @nospecialize(f), @nospecialize(t);
end
nothing
end
code_warntype(@nospecialize(f), @nospecialize(t); kwargs...) =
code_warntype(@nospecialize(f), @nospecialize(t=Base.default_tt(f)); kwargs...) =
code_warntype(stdout, f, t; kwargs...)

import Base.CodegenParams
Expand Down Expand Up @@ -224,9 +224,9 @@ function code_llvm(io::IO, @nospecialize(f), @nospecialize(types), raw::Bool,
print(io, d)
end
end
code_llvm(io::IO, @nospecialize(f), @nospecialize(types=Tuple{}); raw::Bool=false, dump_module::Bool=false, optimize::Bool=true, debuginfo::Symbol=:default) =
code_llvm(io::IO, @nospecialize(f), @nospecialize(types=Base.default_tt(f)); raw::Bool=false, dump_module::Bool=false, optimize::Bool=true, debuginfo::Symbol=:default) =
code_llvm(io, f, types, raw, dump_module, optimize, debuginfo)
code_llvm(@nospecialize(f), @nospecialize(types=Tuple{}); raw=false, dump_module=false, optimize=true, debuginfo::Symbol=:default) =
code_llvm(@nospecialize(f), @nospecialize(types=Base.default_tt(f)); raw=false, dump_module=false, optimize=true, debuginfo::Symbol=:default) =
code_llvm(stdout, f, types; raw, dump_module, optimize, debuginfo)

"""
Expand All @@ -238,7 +238,7 @@ Switch assembly syntax using `syntax` symbol parameter set to `:att` for AT&T sy
Keyword argument `debuginfo` may be one of source (default) or none, to specify the verbosity of code comments.
If `binary` is `true`, it also prints the binary machine code for each instruction precedented by an abbreviated address.
"""
function code_native(io::IO, @nospecialize(f), @nospecialize(types=Tuple{});
function code_native(io::IO, @nospecialize(f), @nospecialize(types=Base.default_tt(f));
dump_module::Bool=true, syntax::Symbol=:att, debuginfo::Symbol=:default, binary::Bool=false)
d = _dump_function(f, types, true, false, false, dump_module, syntax, true, debuginfo, binary)
if highlighting[:native] && get(io, :color, false)
Expand All @@ -247,7 +247,7 @@ function code_native(io::IO, @nospecialize(f), @nospecialize(types=Tuple{});
print(io, d)
end
end
code_native(@nospecialize(f), @nospecialize(types=Tuple{}); dump_module::Bool=true, syntax::Symbol=:att, debuginfo::Symbol=:default, binary::Bool=false) =
code_native(@nospecialize(f), @nospecialize(types=Base.default_tt(f)); dump_module::Bool=true, syntax::Symbol=:att, debuginfo::Symbol=:default, binary::Bool=false) =
code_native(stdout, f, types; dump_module, syntax, debuginfo, binary)
code_native(::IO, ::Any, ::Symbol) = error("invalid code_native call") # resolve ambiguous call

Expand Down
22 changes: 17 additions & 5 deletions stdlib/InteractiveUtils/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -625,11 +625,23 @@ end
end
end

let # default arg types should work for no-arg functions
@test (code_llvm() do
let # `default_tt` should work with any function with one method
@test (code_warntype(devnull, function ()
sin(42)
end; true)
@test (code_native() do
end); true)
@test (code_warntype(devnull, function (a::Int)
sin(a)
end); true)
@test (code_llvm(devnull, function ()
sin(42)
end; true)
end); true)
@test (code_llvm(devnull, function (a::Int)
sin(a)
end); true)
@test (code_native(devnull, function ()
sin(42)
end); true)
@test (code_native(devnull, function (a::Int)
sin(a)
end); true)
end
13 changes: 13 additions & 0 deletions test/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -952,3 +952,16 @@ end
@test only(code_typed(mod.foo, (); world=world1)).second == Int
@test only(code_typed(mod.foo, (); world=world2)).second == Float64
end

@testset "default_tt" begin
m = Module()
@eval m f1() = return
@test Base.default_tt(m.f1) == Tuple{}
@eval m f2(a) = return
@test Base.default_tt(m.f2) == Tuple{Any}
@eval m f3(a::Integer) = return
@test Base.default_tt(m.f3) == Tuple{Integer}
@eval m f4() = return
@eval m f4(a) = return
@test Base.default_tt(m.f4) == Tuple
end

0 comments on commit 0f2d0e2

Please sign in to comment.