Skip to content

Commit

Permalink
fix part of #38936, getfield elim handling union of tuples (#39107)
Browse files Browse the repository at this point in the history
This fixes the regression since 1.5
  • Loading branch information
JeffBezanson authored Jan 7, 2021
1 parent f5c8e67 commit c70a5bc
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 0 deletions.
3 changes: 3 additions & 0 deletions base/compiler/ssair/passes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,9 @@ function getfield_elim_pass!(ir::IRCode)
isa(field, Union{Int, Symbol}) || continue

struct_typ = unwrap_unionall(widenconst(compact_exprtype(compact, stmt.args[2])))
if isa(struct_typ, Union) && struct_typ <: Tuple
struct_typ = unswitchtupleunion(struct_typ)
end
isa(struct_typ, DataType) || continue

def, typeconstraint = stmt.args[2], struct_typ
Expand Down
18 changes: 18 additions & 0 deletions base/compiler/typeutils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,21 @@ function improvable_via_constant_propagation(@nospecialize(t))
end
return false
end

# convert a Union of Tuple types to a Tuple of Unions
function unswitchtupleunion(u::Union)
ts = uniontypes(u)
n = -1
for t in ts
if t isa DataType && t.name === Tuple.name && !isvarargtype(t.parameters[end])
if n == -1
n = length(t.parameters)
elseif n != length(t.parameters)
return u
end
else
return u
end
end
Tuple{Any[ Union{Any[t.parameters[i] for t in ts]...} for i in 1:n ]...}
end
17 changes: 17 additions & 0 deletions test/compiler/irpasses.jl
Original file line number Diff line number Diff line change
Expand Up @@ -352,3 +352,20 @@ let code = code_typed(pi_on_argument, Tuple{Any})[1].first.code,
@test nisa == 1
@test found_pi
end

# issue #38936
# check that getfield elim can handle unions of tuple types
mutable struct S38936{T} content::T end
struct PrintAll{T} <: Function
parts::T
end
function (f::PrintAll)(io::IO)
for x in f.parts
print(io, x)
end
end
let f = PrintAll((S38936("<span>"), "data", S38936("</span")))
@test !any(code_typed(f, (IOBuffer,))[1][1].code) do stmt
stmt isa Expr && stmt.head === :call && stmt.args[1] === GlobalRef(Core, :tuple)
end
end

0 comments on commit c70a5bc

Please sign in to comment.