Skip to content

Commit 178d74d

Browse files
committed
add a version of code_typed that accepts a function type
1 parent be72a57 commit 178d74d

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

base/reflection.jl

+24-2
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,16 @@ function _methods(@nospecialize(f), @nospecialize(t), lim::Int, world::UInt)
834834
return _methods_by_ftype(tt, lim, world)
835835
end
836836

837+
function _methods_ft(@nospecialize(ft::Type), @nospecialize(args), lim::Int, world::UInt)
838+
if isa(args, Type)
839+
u = unwrap_unionall(args)
840+
tt = rewrap_unionall(Tuple{ft, u.parameters...}, args)
841+
else
842+
tt = Tuple{ft, args...}
843+
end
844+
return _methods_by_ftype(tt, lim, world)
845+
end
846+
837847
function _methods_by_ftype(@nospecialize(t), lim::Int, world::UInt)
838848
return _methods_by_ftype(t, lim, world, UInt[typemin(UInt)], UInt[typemax(UInt)])
839849
end
@@ -1081,10 +1091,18 @@ function code_typed(@nospecialize(f), @nospecialize(types=Tuple);
10811091
debuginfo::Symbol=:default,
10821092
world = get_world_counter(),
10831093
interp = Core.Compiler.NativeInterpreter(world))
1084-
ccall(:jl_is_in_pure_context, Bool, ()) && error("code reflection cannot be used from generated functions")
10851094
if isa(f, Core.Builtin)
10861095
throw(ArgumentError("argument is not a generic function"))
10871096
end
1097+
return code_typed_ftype(Core.Typeof(f), types; optimize, debuginfo, world, interp)
1098+
end
1099+
1100+
function code_typed_ftype(@nospecialize(ft), @nospecialize(types=Tuple);
1101+
optimize=true,
1102+
debuginfo::Symbol=:default,
1103+
world = get_world_counter(),
1104+
interp = Core.Compiler.NativeInterpreter(world))
1105+
ccall(:jl_is_in_pure_context, Bool, ()) && error("code reflection cannot be used from generated functions")
10881106
if @isdefined(IRShow)
10891107
debuginfo = IRShow.debuginfo(debuginfo)
10901108
elseif debuginfo === :default
@@ -1095,7 +1113,11 @@ function code_typed(@nospecialize(f), @nospecialize(types=Tuple);
10951113
end
10961114
types = to_tuple_type(types)
10971115
asts = []
1098-
for x in _methods(f, types, -1, world)
1116+
meths = _methods_ft(ft, types, -1, world)
1117+
if meths === false
1118+
error("function type does not correspond to a generic function")
1119+
end
1120+
for x in meths
10991121
meth = func_for_method_checked(x[3], types, x[2])
11001122
(code, ty) = Core.Compiler.typeinf_code(interp, meth, x[1], x[2], optimize)
11011123
code === nothing && error("inference not successful") # inference disabled?

test/reflection.jl

+4
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,10 @@ let
525525
@test !isdefined(mi.cache, :next)
526526
end
527527

528+
# code_typed_ftype
529+
@test Base.code_typed_ftype(Type{<:Val}, ())[1][2] == Val
530+
@test_throws ErrorException("function type does not correspond to a generic function") Base.code_typed_ftype(Any, ())
531+
528532
# New reflection methods in 0.6
529533
struct ReflectionExample{T<:AbstractFloat, N}
530534
x::Tuple{T, N}

0 commit comments

Comments
 (0)