Skip to content

Commit

Permalink
Fix fieldtype_tfunc for union types (#41667)
Browse files Browse the repository at this point in the history
Co-authored-by: Jameson Nash <vtjnash@gmail.com>
  • Loading branch information
martinholters and vtjnash authored Jul 22, 2021
1 parent f540b9c commit 2c02de8
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
15 changes: 13 additions & 2 deletions base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1015,8 +1015,19 @@ function _fieldtype_tfunc(@nospecialize(s), exact::Bool, @nospecialize(name))
exact = exact && !has_free_typevars(s)
u = unwrap_unionall(s)
if isa(u, Union)
return tmerge(_fieldtype_tfunc(rewrap(u.a, s), exact, name),
_fieldtype_tfunc(rewrap(u.b, s), exact, name))
ta0 = _fieldtype_tfunc(rewrap(u.a, s), exact, name)
tb0 = _fieldtype_tfunc(rewrap(u.b, s), exact, name)
ta0 tb0 && return tb0
tb0 ta0 && return ta0
ta, exacta, _, istypea = instanceof_tfunc(ta0)
tb, exactb, _, istypeb = instanceof_tfunc(tb0)
if exact && exacta && exactb
return Const(Union{ta, tb})
end
if istypea && istypeb
return Type{<:Union{ta, tb}}
end
return Any
end
u isa DataType || return Any
if isabstracttype(u)
Expand Down
11 changes: 11 additions & 0 deletions test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3395,3 +3395,14 @@ end
x.x
end) == Any[Int]
end

@testset "fieldtype for unions" begin # e.g. issue #40177
f40177(::Type{T}) where {T} = fieldtype(T, 1)
for T in [
Union{Tuple{Val}, Tuple{Tuple}},
Union{Base.RefValue{T}, Type{Int32}} where T<:Real,
Union{Tuple{Vararg{Symbol}}, Tuple{Float64, Vararg{Float32}}},
]
@test @inferred(f40177(T)) == fieldtype(T, 1)
end
end

0 comments on commit 2c02de8

Please sign in to comment.