Skip to content

Commit cd19e97

Browse files
authored
InteractiveUtils: make default argtype of code_llvm etc. work with functions with single method (#42496)
`code_llvm` and `code_native` expects a single matching method, but the default value of `types=Tuple` argument doesn't match with any function signature and so we actually can't use that default value. With this PR, the default argument type will be computed by `default_tt`, which returns an appropriate signature if a function only has a single method, otherwise returns `Tuple` (which is the same default value as before). Now `code_llvm` and `code_native` by default work with functions that have a single method, e.g.: ```julia code_llvm() do # previously, we need to call `code_llvm(()) do ... end` sin(42) end ```
1 parent 7b76c7e commit cd19e97

File tree

4 files changed

+55
-10
lines changed

4 files changed

+55
-10
lines changed

base/reflection.jl

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,7 +1160,7 @@ additional optimizations, such as inlining, are also applied.
11601160
The keyword `debuginfo` controls the amount of code metadata present in the output,
11611161
possible options are `:source` or `:none`.
11621162
"""
1163-
function code_typed(@nospecialize(f), @nospecialize(types=Tuple);
1163+
function code_typed(@nospecialize(f), @nospecialize(types=default_tt(f));
11641164
optimize=true,
11651165
debuginfo::Symbol=:default,
11661166
world = get_world_counter(),
@@ -1181,6 +1181,18 @@ function code_typed(@nospecialize(f), @nospecialize(types=Tuple);
11811181
return code_typed_by_type(tt; optimize, debuginfo, world, interp)
11821182
end
11831183

1184+
# returns argument tuple type which is supposed to be used for `code_typed` and its family;
1185+
# if there is a single method this functions returns the method argument signature,
1186+
# otherwise returns `Tuple` that doesn't match with any signature
1187+
function default_tt(@nospecialize(f))
1188+
ms = methods(f)
1189+
if length(ms) == 1
1190+
return tuple_type_tail(only(ms).sig)
1191+
else
1192+
return Tuple
1193+
end
1194+
end
1195+
11841196
"""
11851197
code_typed_by_type(types::Type{<:Tuple}; ...)
11861198
@@ -1218,7 +1230,7 @@ function code_typed_by_type(@nospecialize(tt::Type);
12181230
return asts
12191231
end
12201232

1221-
function code_typed_opaque_closure(@nospecialize(closure::Core.OpaqueClosure), @nospecialize(types=Tuple);
1233+
function code_typed_opaque_closure(@nospecialize(closure::Core.OpaqueClosure);
12221234
optimize=true,
12231235
debuginfo::Symbol=:default,
12241236
interp = Core.Compiler.NativeInterpreter(closure.world))
@@ -1232,7 +1244,7 @@ function code_typed_opaque_closure(@nospecialize(closure::Core.OpaqueClosure), @
12321244
end
12331245
end
12341246

1235-
function return_types(@nospecialize(f), @nospecialize(types=Tuple), interp=Core.Compiler.NativeInterpreter())
1247+
function return_types(@nospecialize(f), @nospecialize(types=default_tt(f)), interp=Core.Compiler.NativeInterpreter())
12361248
ccall(:jl_is_in_pure_context, Bool, ()) && error("code reflection cannot be used from generated functions")
12371249
if isa(f, Core.Builtin)
12381250
throw(ArgumentError("argument is not a generic function"))

stdlib/InteractiveUtils/src/codeview.jl

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ Keyword argument `debuginfo` may be one of `:source` or `:none` (default), to sp
5757
5858
See [`@code_warntype`](@ref man-code-warntype) for more information.
5959
"""
60-
function code_warntype(io::IO, @nospecialize(f), @nospecialize(t);
60+
function code_warntype(io::IO, @nospecialize(f), @nospecialize(t=Base.default_tt(f));
6161
debuginfo::Symbol=:default, optimize::Bool=false, kwargs...)
6262
debuginfo = Base.IRShow.debuginfo(debuginfo)
6363
lineprinter = Base.IRShow.__debuginfo[debuginfo]
@@ -134,7 +134,7 @@ function code_warntype(io::IO, @nospecialize(f), @nospecialize(t);
134134
end
135135
nothing
136136
end
137-
code_warntype(@nospecialize(f), @nospecialize(t); kwargs...) =
137+
code_warntype(@nospecialize(f), @nospecialize(t=Base.default_tt(f)); kwargs...) =
138138
code_warntype(stdout, f, t; kwargs...)
139139

140140
import Base.CodegenParams
@@ -224,12 +224,11 @@ function code_llvm(io::IO, @nospecialize(f), @nospecialize(types), raw::Bool,
224224
print(io, d)
225225
end
226226
end
227-
code_llvm(io::IO, @nospecialize(f), @nospecialize(types=Tuple); raw::Bool=false, dump_module::Bool=false, optimize::Bool=true, debuginfo::Symbol=:default) =
227+
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) =
228228
code_llvm(io, f, types, raw, dump_module, optimize, debuginfo)
229-
code_llvm(@nospecialize(f), @nospecialize(types=Tuple); raw=false, dump_module=false, optimize=true, debuginfo::Symbol=:default) =
229+
code_llvm(@nospecialize(f), @nospecialize(types=Base.default_tt(f)); raw=false, dump_module=false, optimize=true, debuginfo::Symbol=:default) =
230230
code_llvm(stdout, f, types; raw, dump_module, optimize, debuginfo)
231231

232-
233232
"""
234233
code_native([io=stdout,], f, types; syntax=:att, debuginfo=:default, binary=false, dump_module=true)
235234
@@ -239,7 +238,7 @@ Switch assembly syntax using `syntax` symbol parameter set to `:att` for AT&T sy
239238
Keyword argument `debuginfo` may be one of source (default) or none, to specify the verbosity of code comments.
240239
If `binary` is `true`, it also prints the binary machine code for each instruction precedented by an abbreviated address.
241240
"""
242-
function code_native(io::IO, @nospecialize(f), @nospecialize(types=Tuple);
241+
function code_native(io::IO, @nospecialize(f), @nospecialize(types=Base.default_tt(f));
243242
dump_module::Bool=true, syntax::Symbol=:att, debuginfo::Symbol=:default, binary::Bool=false)
244243
d = _dump_function(f, types, true, false, false, dump_module, syntax, true, debuginfo, binary)
245244
if highlighting[:native] && get(io, :color, false)
@@ -248,7 +247,7 @@ function code_native(io::IO, @nospecialize(f), @nospecialize(types=Tuple);
248247
print(io, d)
249248
end
250249
end
251-
code_native(@nospecialize(f), @nospecialize(types=Tuple); dump_module::Bool=true, syntax::Symbol=:att, debuginfo::Symbol=:default, binary::Bool=false) =
250+
code_native(@nospecialize(f), @nospecialize(types=Base.default_tt(f)); dump_module::Bool=true, syntax::Symbol=:att, debuginfo::Symbol=:default, binary::Bool=false) =
252251
code_native(stdout, f, types; dump_module, syntax, debuginfo, binary)
253252
code_native(::IO, ::Any, ::Symbol) = error("invalid code_native call") # resolve ambiguous call
254253

stdlib/InteractiveUtils/test/runtests.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,3 +649,24 @@ end
649649
end
650650
end
651651
end
652+
653+
let # `default_tt` should work with any function with one method
654+
@test (code_warntype(devnull, function ()
655+
sin(42)
656+
end); true)
657+
@test (code_warntype(devnull, function (a::Int)
658+
sin(a)
659+
end); true)
660+
@test (code_llvm(devnull, function ()
661+
sin(42)
662+
end); true)
663+
@test (code_llvm(devnull, function (a::Int)
664+
sin(a)
665+
end); true)
666+
@test (code_native(devnull, function ()
667+
sin(42)
668+
end); true)
669+
@test (code_native(devnull, function (a::Int)
670+
sin(a)
671+
end); true)
672+
end

test/reflection.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -952,3 +952,16 @@ end
952952
@test only(code_typed(mod.foo, (); world=world1)).second == Int
953953
@test only(code_typed(mod.foo, (); world=world2)).second == Float64
954954
end
955+
956+
@testset "default_tt" begin
957+
m = Module()
958+
@eval m f1() = return
959+
@test Base.default_tt(m.f1) == Tuple{}
960+
@eval m f2(a) = return
961+
@test Base.default_tt(m.f2) == Tuple{Any}
962+
@eval m f3(a::Integer) = return
963+
@test Base.default_tt(m.f3) == Tuple{Integer}
964+
@eval m f4() = return
965+
@eval m f4(a) = return
966+
@test Base.default_tt(m.f4) == Tuple
967+
end

0 commit comments

Comments
 (0)