From 27e83c06f7fec28fb582c8e010372d623b7b70d7 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Thu, 23 Apr 2020 23:57:56 -0700 Subject: [PATCH 1/3] Improve typesubtract for tuples --- base/compiler/typeutils.jl | 6 ++++++ test/compiler/inference.jl | 41 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/base/compiler/typeutils.jl b/base/compiler/typeutils.jl index ebb06a33a2d74..3ccf426dc48c1 100644 --- a/base/compiler/typeutils.jl +++ b/base/compiler/typeutils.jl @@ -70,6 +70,12 @@ function typesubtract(@nospecialize(a), @nospecialize(b)) if isa(a, Union) return Union{typesubtract(a.a, b), typesubtract(a.b, b)} + elseif a isa DataType && b isa DataType && a.name === b.name === Tuple.name && + length(a.types) == length(b.types) + ta = switchtupleunion(a) + if length(ta) > 1 + return typesubtract(Union{ta...}, b) + end end return a # TODO: improve this bound? end diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index 26371e7927005..0f8b0671ae5d6 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -2545,3 +2545,44 @@ end @test only(Base.code_typed(pickvarnames, (Vector{Any},), optimize=false))[2] == Tuple{Vararg{Union{Symbol, Tuple{Vararg{Union{Symbol, Tuple}}}}}} @test map(>:, [Int], [Int]) == [true] + +# issue 35566 +module Issue35566 +function step(acc, x) + xs, = acc + y = x > 0.0 ? x : missing + if y isa eltype(xs) + ys = push!(xs, y) + else + ys = vcat(xs, [y]) + end + return (ys,) +end + +function probe(y) + if y isa Tuple{Vector{Missing}} + return Val(:missing) + else + return Val(:expected) + end +end + +function _foldl_iter(rf, val::T, iter, state) where {T} + while true + ret = iterate(iter, state) + ret === nothing && break + x, state = ret + y = rf(val, x) + if y isa T + val = y + else + return probe(y) + end + end + return Val(:expected) +end + +f() = _foldl_iter(step, (Missing[],), [0.0], 1) +end +@test Core.Compiler.typesubtract(Tuple{Union{Int,Char}}, Tuple{Char}) == Tuple{Int} +@test Base.return_types(Issue35566.f) == [Val(:expected)] From 2909bfdc1c4dc11ffaeee3067e633128cc17b900 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Sat, 25 Apr 2020 18:35:37 -0700 Subject: [PATCH 2/3] Fix test --- test/compiler/inference.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index 0f8b0671ae5d6..fd2e6138e561d 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -2585,4 +2585,4 @@ end f() = _foldl_iter(step, (Missing[],), [0.0], 1) end @test Core.Compiler.typesubtract(Tuple{Union{Int,Char}}, Tuple{Char}) == Tuple{Int} -@test Base.return_types(Issue35566.f) == [Val(:expected)] +@test Base.return_types(Issue35566.f) == [Val{:expected}] From b15bf344fe89b7046ae9742f44adf7259f55ac35 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Sun, 26 Apr 2020 14:19:29 -0700 Subject: [PATCH 3/3] Apply suggestions from code review Co-Authored-By: Jameson Nash --- base/compiler/typeutils.jl | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/base/compiler/typeutils.jl b/base/compiler/typeutils.jl index 3ccf426dc48c1..d6eb7305b1c8d 100644 --- a/base/compiler/typeutils.jl +++ b/base/compiler/typeutils.jl @@ -70,11 +70,14 @@ function typesubtract(@nospecialize(a), @nospecialize(b)) if isa(a, Union) return Union{typesubtract(a.a, b), typesubtract(a.b, b)} - elseif a isa DataType && b isa DataType && a.name === b.name === Tuple.name && - length(a.types) == length(b.types) - ta = switchtupleunion(a) - if length(ta) > 1 - return typesubtract(Union{ta...}, b) + elseif a isa DataType + if b isa DataType + if a.name === b.name === Tuple.name && length(a.types) == length(b.types) + ta = switchtupleunion(a) + if length(ta) > 1 + return typesubtract(Union{ta...}, b) + end + end end end return a # TODO: improve this bound?