Trying to understand inferred effects

julia> Base.infer_effects(getindex, (UnitRange{Int}, Int))
(+c,+e,!n,+t,+s,+m,+u)

julia> Base.infer_effects(getindex, (Base.OneTo{Int}, Int))
(!c,+e,!n,+t,+s,+m,+u)

julia> VERSION
v"1.12.0-DEV.88"

Firstly, why is the inbounds effect not displayed (there are seven flags, not eight), even though the documentation says that this should be there? Secondly, why is the consistent flag different between the two? Indexing a Base.OneTo is a simpler operation, so I would have naively expected the flag to hold as well. I noticed that the getindex for a UnitRange{Int} with an Int index uses val % T instead of convert(T, val), so is this what is leading to the difference? These should both be no-ops, so I don’t see why this difference should matter. (it doesn’t)

this appears to be a bug.

As for the first point, this is just because the documentation for Core.Compiler.Effects isn’t synced with the latest implementation. We should update it.

2 Likes

The second issue definitely is a bug. Actually, getindex(::Base.OneTo, ...) and getindex(::UnitRange, ...) both include @boundscheck and their behavior is changed by the caller’s @inbounds context, meaning they shouldn’t be considered :consistent.
See post-opt analysis bug: wrongly refine `:consistent` of `Base._getindex(::Base.OneTo{Int}, ::Int)` · Issue #53508 · JuliaLang/julia · GitHub for more details.

2 Likes