diff --git a/src/internals.jl b/src/internals.jl index efcbcdd..6b5a43d 100644 --- a/src/internals.jl +++ b/src/internals.jl @@ -2,6 +2,20 @@ module Internals import StableTasks: @spawn, @spawnat, @fetch, @fetchfrom, StableTask, AtomicRef +if ( + (@isdefined Core) && + (Core isa Module) && + isdefined(Core, :Compiler) && + (Core.Compiler isa Module) && + isdefined(Core.Compiler, :return_type) && + applicable(Core.Compiler.return_type, identity, Tuple{}) +) + infer_return_type(@nospecialize f::Any) = Core.Compiler.return_type(f, Tuple{}) +else + # safe conservative fallback to `Any`, which is subtyped by each type + infer_return_type(@nospecialize f::Any) = Any +end + Base.getindex(r::AtomicRef) = @atomic r.x Base.setindex!(r::AtomicRef{T}, x) where {T} = @atomic r.x = convert(T, x) @@ -96,7 +110,7 @@ macro spawn(args...) quote let $(letargs...) f = $thunk - T = Core.Compiler.return_type(f, Tuple{}) + T = infer_return_type(f) ref = AtomicRef{T}() f_wrap = () -> (ref[] = f(); nothing) task = Task(f_wrap) @@ -136,7 +150,7 @@ macro spawnat(thrdid, ex) end let $(letargs...) thunk = $thunk - RT = Core.Compiler.return_type(thunk, Tuple{}) + RT = infer_return_type(thunk) ret = AtomicRef{RT}() thunk_wrap = () -> (ret[] = thunk(); nothing) local task = Task(thunk_wrap)