Ok, well, this seems like it works on 0.7
struct Key{T <: Any} end
Key(x) = Key{x}()
Base.@pure argtail(x, rest...) = rest
tail(x) = argtail(x...)
Base.show(io::IO, ::Key{T}) where T = begin
print(io, ".")
print(io, T)
end
next_item(t::Tuple, reference_key::T, next_key::T) where T <: Key =
first(t)
next_item(t::Tuple{}, reference_key::T, next_key::T) where T <: Key =
error("No item after key $reference_key")
next_item(t::Tuple, reference_key::Key, next_key) =
get_key(t, reference_key)
next_item(t::Tuple{}, reference_key::Key, next_key) =
error("Key $reference_key not found")
get_key(t::Tuple, k::Key) = next_item(tail(t), k, first(t))
get_key(t::Tuple{}, k::Key) = error("Can't index an empty tuple")
Base.getproperty(t::Tuple, k::Symbol) = get_key(t, Key(k))
function test()
x = (Key(:a), 1, Key(:b), 2)
x.b
end
@code_warntype test()
Involves a bit of type piracy, but