Skip to content

Commit 0c0dfc4

Browse files
committed
better abstract type inference for oftype
Achieve better abstract return type inference by moving the typeassert to after the branch, so it affects both sides of the branch. Also deduplicate `typeof(x)` calls.
1 parent 2f34760 commit 0c0dfc4

File tree

2 files changed

+8
-1
lines changed

2 files changed

+8
-1
lines changed

base/essentials.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,10 @@ julia> oftype(y, x)
696696
4.0
697697
```
698698
"""
699-
oftype(x, y) = y isa typeof(x) ? y : convert(typeof(x), y)::typeof(x)
699+
function oftype(x, y)
700+
X = typeof(x)
701+
(y isa X ? y : convert(X, y))::X
702+
end
700703

701704
unsigned(x::Int) = reinterpret(UInt, x)
702705
signed(x::UInt) = reinterpret(Int, x)

test/core.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8094,6 +8094,10 @@ end
80948094
f_isdefined_one(@nospecialize(x)) = isdefined(x, 1)
80958095
@test (try; f_isdefined_one(@__MODULE__); catch err; err; end).got === 1
80968096

8097+
@testset "worst case abstract type inference for `oftype`" begin
8098+
@test Number === Base.infer_return_type(oftype, Tuple{Number, Any})
8099+
end
8100+
80978101
# Unspecialized retrieval of vararg length
80988102
fvarargN(x::Tuple{Vararg{Int, N}}) where {N} = N
80998103
fvarargN(args...) = fvarargN(args)

0 commit comments

Comments
 (0)