Commit e496b2e
authored
Fix type instability in convs using CompoundPeriod (JuliaLang#54995)
The functions `toms`, `tons`, and `days` uses `sum` over a vector of
`Period`s to obtain the conversion of a `CompoundPeriod`. However, the
compiler cannot infer the return type because those functions can return
either `Int` or `Float` depending on the type of the `Period`. This PR
forces the result of those functions to be `Float64`, fixing the type
stability.
Before this PR we had:
```julia
julia> using Dates
julia> p = Dates.Second(1) + Dates.Minute(1) + Dates.Year(1)
1 year, 1 minute, 1 second
julia> @code_warntype Dates.tons(p)
MethodInstance for Dates.tons(::Dates.CompoundPeriod)
from tons(c::Dates.CompoundPeriod) @ Dates ~/.julia/juliaup/julia-nightly/share/julia/stdlib/v1.12/Dates/src/periods.jl:458
Arguments
#self#::Core.Const(Dates.tons)
c::Dates.CompoundPeriod
Body::Any
1 ─ %1 = Dates.isempty::Core.Const(isempty)
│ %2 = Base.getproperty(c, :periods)::Vector{Period}
│ %3 = (%1)(%2)::Bool
└── goto mmtk#3 if not %3
2 ─ return 0.0
3 ─ %6 = Dates.Float64::Core.Const(Float64)
│ %7 = Dates.sum::Core.Const(sum)
│ %8 = Dates.tons::Core.Const(Dates.tons)
│ %9 = Base.getproperty(c, :periods)::Vector{Period}
│ %10 = (%7)(%8, %9)::Any
│ %11 = (%6)(%10)::Any
└── return %11
julia> @code_warntype Dates.toms(p)
MethodInstance for Dates.toms(::Dates.CompoundPeriod)
from toms(c::Dates.CompoundPeriod) @ Dates ~/.julia/juliaup/julia-nightly/share/julia/stdlib/v1.12/Dates/src/periods.jl:454
Arguments
#self#::Core.Const(Dates.toms)
c::Dates.CompoundPeriod
Body::Any
1 ─ %1 = Dates.isempty::Core.Const(isempty)
│ %2 = Base.getproperty(c, :periods)::Vector{Period}
│ %3 = (%1)(%2)::Bool
└── goto mmtk#3 if not %3
2 ─ return 0.0
3 ─ %6 = Dates.Float64::Core.Const(Float64)
│ %7 = Dates.sum::Core.Const(sum)
│ %8 = Dates.toms::Core.Const(Dates.toms)
│ %9 = Base.getproperty(c, :periods)::Vector{Period}
│ %10 = (%7)(%8, %9)::Any
│ %11 = (%6)(%10)::Any
└── return %11
julia> @code_warntype Dates.days(p)
MethodInstance for Dates.days(::Dates.CompoundPeriod)
from days(c::Dates.CompoundPeriod) @ Dates ~/.julia/juliaup/julia-nightly/share/julia/stdlib/v1.12/Dates/src/periods.jl:468
Arguments
#self#::Core.Const(Dates.days)
c::Dates.CompoundPeriod
Body::Any
1 ─ %1 = Dates.isempty::Core.Const(isempty)
│ %2 = Base.getproperty(c, :periods)::Vector{Period}
│ %3 = (%1)(%2)::Bool
└── goto mmtk#3 if not %3
2 ─ return 0.0
3 ─ %6 = Dates.Float64::Core.Const(Float64)
│ %7 = Dates.sum::Core.Const(sum)
│ %8 = Dates.days::Core.Const(Dates.days)
│ %9 = Base.getproperty(c, :periods)::Vector{Period}
│ %10 = (%7)(%8, %9)::Any
│ %11 = (%6)(%10)::Any
└── return %11
```
After this PR we have:
```julia
julia> using Dates
julia> p = Dates.Second(1) + Dates.Minute(1) + Dates.Year(1)
1 year, 1 minute, 1 second
julia> @code_warntype Dates.tons(p)
MethodInstance for Dates.tons(::Dates.CompoundPeriod)
from tons(c::Dates.CompoundPeriod) @ Dates ~/.julia/juliaup/julia-nightly/share/julia/stdlib/v1.12/Dates/src/periods.jl:458
Arguments
#self#::Core.Const(Dates.tons)
c::Dates.CompoundPeriod
Body::Float64
1 ─ %1 = Dates.isempty::Core.Const(isempty)
│ %2 = Base.getproperty(c, :periods)::Vector{Period}
│ %3 = (%1)(%2)::Bool
└── goto mmtk#3 if not %3
2 ─ return 0.0
3 ─ %6 = Dates.Float64::Core.Const(Float64)
│ %7 = Dates.sum::Core.Const(sum)
│ %8 = Dates.tons::Core.Const(Dates.tons)
│ %9 = Base.getproperty(c, :periods)::Vector{Period}
│ %10 = (%7)(%8, %9)::Any
│ %11 = (%6)(%10)::Any
│ %12 = Dates.Float64::Core.Const(Float64)
│ %13 = Core.typeassert(%11, %12)::Float64
└── return %13
julia> @code_warntype Dates.toms(p)
MethodInstance for Dates.toms(::Dates.CompoundPeriod)
from toms(c::Dates.CompoundPeriod) @ Dates ~/.julia/juliaup/julia-nightly/share/julia/stdlib/v1.12/Dates/src/periods.jl:454
Arguments
#self#::Core.Const(Dates.toms)
c::Dates.CompoundPeriod
Body::Float64
1 ─ %1 = Dates.isempty::Core.Const(isempty)
│ %2 = Base.getproperty(c, :periods)::Vector{Period}
│ %3 = (%1)(%2)::Bool
└── goto mmtk#3 if not %3
2 ─ return 0.0
3 ─ %6 = Dates.Float64::Core.Const(Float64)
│ %7 = Dates.sum::Core.Const(sum)
│ %8 = Dates.toms::Core.Const(Dates.toms)
│ %9 = Base.getproperty(c, :periods)::Vector{Period}
│ %10 = (%7)(%8, %9)::Any
│ %11 = (%6)(%10)::Any
│ %12 = Dates.Float64::Core.Const(Float64)
│ %13 = Core.typeassert(%11, %12)::Float64
└── return %13
julia> @code_warntype Dates.days(p)
MethodInstance for Dates.days(::Dates.CompoundPeriod)
from days(c::Dates.CompoundPeriod) @ Dates ~/.julia/juliaup/julia-nightly/share/julia/stdlib/v1.12/Dates/src/periods.jl:468
Arguments
#self#::Core.Const(Dates.days)
c::Dates.CompoundPeriod
Body::Float64
1 ─ %1 = Dates.isempty::Core.Const(isempty)
│ %2 = Base.getproperty(c, :periods)::Vector{Period}
│ %3 = (%1)(%2)::Bool
└── goto mmtk#3 if not %3
2 ─ return 0.0
3 ─ %6 = Dates.Float64::Core.Const(Float64)
│ %7 = Dates.sum::Core.Const(sum)
│ %8 = Dates.days::Core.Const(Dates.days)
│ %9 = Base.getproperty(c, :periods)::Vector{Period}
│ %10 = (%7)(%8, %9)::Any
│ %11 = (%6)(%10)::Any
│ %12 = Dates.Float64::Core.Const(Float64)
│ %13 = Core.typeassert(%11, %12)::Float64
└── return %13
```1 parent df3fe22 commit e496b2e
1 file changed
+3
-3
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
451 | 451 | | |
452 | 452 | | |
453 | 453 | | |
454 | | - | |
| 454 | + | |
455 | 455 | | |
456 | 456 | | |
457 | 457 | | |
458 | | - | |
| 458 | + | |
459 | 459 | | |
460 | 460 | | |
461 | 461 | | |
| |||
465 | 465 | | |
466 | 466 | | |
467 | 467 | | |
468 | | - | |
| 468 | + | |
469 | 469 | | |
470 | 470 | | |
471 | 471 | | |
| |||
0 commit comments