Skip to content

Commit 533dbbd

Browse files
committed
safer access to Julia's type inference
* Only access an implementation detail of Julia when it's available, falling back to `Any` as an accurate but possibly imprecise approximation of the return type. * Prefer `Base.infer_return_type` to `Core.Compiler.return_type` * The former is more public than the latter: * JuliaLang/julia#53105 (comment) * Warning/TODO: both of these accept a world age as an optional parameter, but differ (?) in the default value choice. Thus it might be necessary to provide a world age explicitly, not sure. Relevant links to the Julia code base: * `Core.Compiler.return_type`: * https://github.com/JuliaLang/julia/blob/99a764750ef4e53214f2247d186ff4aac4f91983/Compiler/src/typeinfer.jl#L1416-L1434 * `Base.infer_return_type` * https://github.com/JuliaLang/julia/blob/99a764750ef4e53214f2247d186ff4aac4f91983/base/reflection.jl#L534-L601
1 parent 88da813 commit 533dbbd

File tree

1 file changed

+22
-2
lines changed

1 file changed

+22
-2
lines changed

src/internals.jl

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,26 @@ module Internals
22

33
import StableTasks: @spawn, @spawnat, @fetch, @fetchfrom, StableTask, AtomicRef
44

5+
# * use `Base.infer_return_type` in preference to `Core.Compiler.return_type`
6+
# * safe conservative fallback to `Any`, which is subtyped by each type
7+
if (
8+
isdefined(Base, :infer_return_type) &&
9+
applicable(Base.infer_return_type, identity, Tuple{})
10+
)
11+
infer_return_type(@nospecialize f::Any) = Base.infer_return_type(f, Tuple{})
12+
elseif (
13+
(@isdefined Core) &&
14+
(Core isa Module) &&
15+
isdefined(Core, :Compiler) &&
16+
(Core.Compiler isa Module) &&
17+
isdefined(Core.Compiler, :return_type) &&
18+
applicable(Core.Compiler.return_type, identity, Tuple{})
19+
)
20+
infer_return_type(@nospecialize f::Any) = Core.Compiler.return_type(f, Tuple{})
21+
else
22+
infer_return_type(@nospecialize f::Any) = Any
23+
end
24+
525
Base.getindex(r::AtomicRef) = @atomic r.x
626
Base.setindex!(r::AtomicRef{T}, x) where {T} = @atomic r.x = convert(T, x)
727

@@ -96,7 +116,7 @@ macro spawn(args...)
96116
quote
97117
let $(letargs...)
98118
f = $thunk
99-
T = Core.Compiler.return_type(f, Tuple{})
119+
T = infer_return_type(f)
100120
ref = AtomicRef{T}()
101121
f_wrap = () -> (ref[] = f(); nothing)
102122
task = Task(f_wrap)
@@ -136,7 +156,7 @@ macro spawnat(thrdid, ex)
136156
end
137157
let $(letargs...)
138158
thunk = $thunk
139-
RT = Core.Compiler.return_type(thunk, Tuple{})
159+
RT = infer_return_type(thunk)
140160
ret = AtomicRef{RT}()
141161
thunk_wrap = () -> (ret[] = thunk(); nothing)
142162
local task = Task(thunk_wrap)

0 commit comments

Comments
 (0)