JuliaFolds / Transducers.jl

Efficient transducers for Julia
https://juliafolds.github.io/Transducers.jl/dev/
MIT License
433 stars 24 forks source link

Faulty assumptions in `_might_return_reduced` #537

Closed MasonProtter closed 1 year ago

MasonProtter commented 1 year ago

The code in https://github.com/JuliaFolds/Transducers.jl/blob/958213c0b5bf78814d6ac1e43668f8ceb84a6bf0/src/reduce.jl#L218-L244 relies on Julia's type inference algorithm not realizing that the code always errors. 1.9's inference is now smart enough that this no longer works:

1.8.0:

julia> using Transducers

julia> Transducers._might_return_reduced(reducingfunction(ReduceIf(ismissing), +), 0, (0, missing))
true

julia> Core.Compiler.return_type(Transducers._reduce_dummy,  # simulate the output type of `_reduce`
                   typeof((reducingfunction(ReduceIf(ismissing), +), 0, (0, missing))),
               )
Reduced{Missing}

julia> Transducers._reduce_dummy(reducingfunction(ReduceIf(ismissing), +), 0, (0, missing))
ERROR: MethodError: no method matching halve(::Transducers.SizedReducible{Tuple{Int64, Missing}, Int64})
Closest candidates are:
...

Julia Master realizes this will error and gives us a Union{}

julia> using Transducers

julia> Core.Compiler.return_type(Transducers._reduce_dummy,  # simulate the output type of `_reduce`
                   typeof((reducingfunction(ReduceIf(ismissing), +), 0, (0, missing))),
               )
Union{}

which makes it so that _might_return_reduced gives false.