Skip to content

Commit 18a2031

Browse files
authored
improve return-type reflections of opaque closure (JuliaLang#44743)
1 parent 54be1ce commit 18a2031

File tree

2 files changed

+19
-6
lines changed

2 files changed

+19
-6
lines changed

base/reflection.jl

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,16 +1276,16 @@ function code_typed_by_type(@nospecialize(tt::Type);
12761276
return asts
12771277
end
12781278

1279-
function code_typed_opaque_closure(@nospecialize(closure::Core.OpaqueClosure);
1280-
optimize=true,
1281-
debuginfo::Symbol=:default,
1282-
interp = Core.Compiler.NativeInterpreter(closure.world))
1279+
function code_typed_opaque_closure(@nospecialize(oc::Core.OpaqueClosure);
1280+
debuginfo::Symbol=:default, __...)
12831281
ccall(:jl_is_in_pure_context, Bool, ()) && error("code reflection cannot be used from generated functions")
1284-
m = closure.source
1282+
m = oc.source
12851283
if isa(m, Method)
12861284
code = _uncompressed_ir(m, m.source)
12871285
debuginfo === :none && remove_linenums!(code)
1288-
return Any[(code => code.rettype)]
1286+
# intersect the declared return type and the inferred return type (if available)
1287+
rt = typeintersect(code.rettype, typeof(oc).parameters[2])
1288+
return Any[code => rt]
12891289
else
12901290
error("encountered invalid Core.OpaqueClosure object")
12911291
end
@@ -1295,6 +1295,10 @@ function return_types(@nospecialize(f), @nospecialize(types=default_tt(f));
12951295
world = get_world_counter(),
12961296
interp = Core.Compiler.NativeInterpreter(world))
12971297
ccall(:jl_is_in_pure_context, Bool, ()) && error("code reflection cannot be used from generated functions")
1298+
if isa(f, Core.OpaqueClosure)
1299+
_, rt = only(code_typed_opaque_closure(f))
1300+
return Any[rt]
1301+
end
12981302
types = to_tuple_type(types)
12991303
rt = []
13001304
for match in _methods(f, types, -1, world)::Vector

test/opaque_closure.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,15 @@ const GLOBAL_OPAQUE_CLOSURE = @opaque () -> 123
227227
call_global_opaque_closure() = GLOBAL_OPAQUE_CLOSURE()
228228
@test call_global_opaque_closure() == 123
229229

230+
let foo::Int = 42
231+
Base.Experimental.@force_compile
232+
oc = Base.Experimental.@opaque a::Int->sin(a) + cos(foo)
233+
234+
@test only(Base.return_types(oc, (Int,))) === Float64
235+
code, rt = first(code_typed(oc, (Int,)))
236+
@test rt === Float64
237+
end
238+
230239
let oc = @opaque a->sin(a)
231240
@test length(code_typed(oc, (Int,))) == 1
232241
end

0 commit comments

Comments
 (0)