From 2c02de80bd7ec2e33378e75be34635c072d06a60 Mon Sep 17 00:00:00 2001 From: Martin Holters Date: Thu, 22 Jul 2021 07:41:31 +0200 Subject: [PATCH] Fix `fieldtype_tfunc` for union types (#41667) Co-authored-by: Jameson Nash --- base/compiler/tfuncs.jl | 15 +++++++++++++-- test/compiler/inference.jl | 11 +++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/base/compiler/tfuncs.jl b/base/compiler/tfuncs.jl index e078567f9a59b..09aa05f35b9f0 100644 --- a/base/compiler/tfuncs.jl +++ b/base/compiler/tfuncs.jl @@ -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) diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index 008e6ff0d6997..4d7aed372f6c8 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -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