From f8fc5faded74385cfae15659c3c0901757d6a731 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Tue, 14 Jan 2020 11:47:28 -0800 Subject: [PATCH] Fix initial value handling with flatten transducer (#34369) There was a bug in initial value handling of `FlatteningRF` and the following example failed: @test mapfoldl( x -> (x, x), ((a, b), (c, d)) -> (min(a, c), max(b, d)), Iterators.flatten((1:2, 3:4)), ) == (1, 4) This is because `BottomRF(op.rf)` was called inside `FlatteningRF` where `op.rf` is already a "non-bottom" reducing function; here it's a `MappingRF`. As `BottomRF(rf)` forwards anything on the second argument on the first invocation as the first argument (accumulator) of the next calls, we need to make sure that this value is processed through `MappingRF` in the above example. However, if we do `BottomRF(op.rf)` where `op.rf` is a `MappingRF`, this `BottomRF` bypasses any processing that has to happen in `op.rf`. (cherry picked from commit 0ee3264be377a70e56465142649e67b4f85dda12) --- base/reduce.jl | 2 +- test/reduce.jl | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/base/reduce.jl b/base/reduce.jl index 2c97effdf9550..c89e7b8763547 100644 --- a/base/reduce.jl +++ b/base/reduce.jl @@ -112,7 +112,7 @@ struct FlatteningRF{T} end @inline function (op::FlatteningRF)(acc, x) - op′, itr′ = _xfadjoint(BottomRF(op.rf), x) + op′, itr′ = _xfadjoint(op.rf, x) return _foldl_impl(op′, acc, itr′) end diff --git a/test/reduce.jl b/test/reduce.jl index e57e964002ea2..4a852d3097135 100644 --- a/test/reduce.jl +++ b/test/reduce.jl @@ -535,3 +535,11 @@ x = [j^2 for j in i] i = Base.Slice(0:0) x = [j+7 for j in i] @test sum(x) == 7 + +@testset "initial value handling with flatten" begin + @test mapfoldl( + x -> (x, x), + ((a, b), (c, d)) -> (min(a, c), max(b, d)), + Iterators.flatten((1:2, 3:4)), + ) == (1, 4) +end