Help me understand constant propagation

Alright, here is a better example. This is a pared-down version of what I’m doing in ComponentArrays.jl. I’m using @inline for getindex here and am still seeing the issue.

idx_ax(x) = (x, NamedTuple())
idx_ax(x::Tuple) = x

struct Axis{IdxMap} end
Axis(IdxMap) = Axis{IdxMap}()

struct ComponentArray{Axes,T,N,A<:AbstractArray{T,N}} <: AbstractArray{T,N}
    data::A
    axes::Axes
    ComponentArray(data::A, ax::Ax) where {A<:AbstractArray{T,N},Ax<:Axis} where {T,N} = new{Ax,T,N,A}(data, ax)
    ComponentArray(data, ax) = data
end

@inline getdata(x::ComponentArray) = getfield(x, :data)
@inline getaxes(x::ComponentArray) = getfield(x, :axes)
@inline getaxes(::Type{ComponentArray{Ax,T,N,A}}) where {Ax<:Axis,T,N,A} = Ax

Base.size(x::ComponentArray) = size(getdata(x))

@inline Base.getindex(x::ComponentArray, s::Symbol) = _getindex(x, Val(s))
@inline Base.getindex(x::ComponentArray, idx) = getdata(x)[idx]
@inline Base.getindex(::Type{Axis{IdxMap}}, s::Symbol) where IdxMap = idx_ax(getfield(IdxMap, s))

@generated function _getindex(x::ComponentArray, ::Val{s}) where s
    ind_tup = getindex(getaxes(x), s)
    idx = ind_tup[1]
    new_ax = Axis(ind_tup[2])
    return :(Base.@_inline_meta; ComponentArray(Base.maybeview(getdata(x), $idx), $new_ax))
end

@inline Base.getproperty(x::ComponentArray, s::Symbol) = _getindex(x, Val(s))

Constant propagation works just fine on getproperty, but I can’t seem to get it to work with getindex:

ax = Axis((a=1, b=2:4, c=(5:8, (a=1:3, b=4))))
ca = ComponentArray(rand(8), ax)


using BenchmarkTools

@btime $ca.a       # 1.099 ns (0 allocations: 0 bytes)
@btime $ca[:a]     # 4.314 μs (1 allocation: 16 bytes)

@btime $ca.c.b     # 1.099 ns (0 allocations: 0 bytes)
@btime $ca[:c][:b] # 8.933 μs (3 allocations: 80 bytes)

@btime $ca.c.a     # 13.300 ns (2 allocations: 64 bytes)
@btime $ca[:c][:a] # 8.833 μs (4 allocations: 128 bytes)


function test_prop(x)
    return getproperty(x, :c)
end

function test_index(x)
    return getindex(x, :c)
end

@btime test_prop($ca)  # 13.400 ns (2 allocations: 64 bytes)
@btime test_index($ca) # 4.386 μs (2 allocations: 64 bytes)