I am wondering if the following is a bug, or something I am missing. MWE:
struct Foo{T}
a::T
b::T
end
function struct2nt(x::T) where T
@assert isstructtype(T)
N = fieldnames(T)
NamedTuple{N}(getfield(x, n) for n in N)
end
struct2nt(Foo(2, 3)) # works fine
@code_warntype struct2nt(Foo(2, 3)) # errors
On 1.11 and 1.12rc, errors with
julia> @code_warntype struct2nt(Foo(2, 3))
MethodInstance for struct2nt(::Foo{Int64})
from struct2nt(x::T) where T @ Main REPL[1]:1
Static Parameters
T = Foo{Int64}
Arguments
#self#::Core.Const(Main.struct2nt)
x::Foo{Int64}
Locals
#3::var"#3#4"{Foo{Int64}}
N::Tuple{Symbol, Symbol}
BodyERROR: BoundsError: attempt to access Core.SimpleVector at index [2]
Stacktrace:
[1] getindex
@ ./essentials.jl:932 [inlined]
[2] show_at_namedtuple(io::IOContext{IOBuffer}, syms::Tuple{Symbol, Symbol}, types::DataType)
@ Base ./show.jl:1191
[3] show_datatype(io::IOContext{IOBuffer}, x::DataType, wheres::Vector{TypeVar})
@ Base ./show.jl:1167
[4] _show_type(io::IOBuffer, x::Type)
@ Base ./show.jl:1007
[5] show(io::IOBuffer, x::Type)
@ Base ./show.jl:965
[6] print(io::IOBuffer, x::Type)
@ Base ./strings/io.jl:35
[7] print_to_string(::String, ::Vararg{Any})
@ Base ./strings/io.jl:148
[8] string
@ ./strings/io.jl:189 [inlined]
[9] warntype_type_printer(io::Base.TTY; type::Any, used::Bool, show_type::Bool, ::@Kwargs{})
@ InteractiveUtils ~/.julia/juliaup/julia-1.11.6+0.x64.linux.gnu/share/julia/stdlib/v1.11/InteractiveUtils/src/codeview.jl:32
[10] code_warntype(io::Base.TTY, f::Any, t::Any; debuginfo::Symbol, optimize::Bool, kwargs::@Kwargs{})
@ InteractiveUtils ~/.julia/juliaup/julia-1.11.6+0.x64.linux.gnu/share/julia/stdlib/v1.11/InteractiveUtils/src/codeview.jl:151
[11] code_warntype(io::Base.TTY, f::Any, t::Any)
@ InteractiveUtils ~/.julia/juliaup/julia-1.11.6+0.x64.linux.gnu/share/julia/stdlib/v1.11/InteractiveUtils/src/codeview.jl:77
[12] code_warntype(::Any, ::Vararg{Any}; kwargs...)
@ InteractiveUtils ~/.julia/juliaup/julia-1.11.6+0.x64.linux.gnu/share/julia/stdlib/v1.11/InteractiveUtils/src/codeview.jl:159
[13] top-level scope
@ REPL[5]:1
which works fine. I tried Debugger.jl on @code_warntype and the expanded call, but trying to advance by 1 step on much earlier calls apparently jumps to executing the code_warntype call, which of course errors.
function Base.show_at_namedtuple(io::IO, syms::Tuple, types::DataType)
first = true
for i in eachindex(syms)
if !first
print(io, ", ")
end
print(io, syms[i])
typ = types.parameters[i] # here the error occurs
if typ !== Any
print(io, "::")
show(io, typ)
end
first = false
end
end
is called with types set to NTuple{N, Int}. I guess this is a fragment of some NTuple{N, Int} where N.
global X = nothing
function Base.show(io::IO, @nospecialize(x::Type))
try
Base._show_type(io, Base.inferencebarrier(x))
catch e
global X = x
rethrow(e)
end
end
and indeed there seems to be something missing (X is unprintable):
It appears to work fine in 1.6, so I guess we should be able to bisect it. (I don’t have time right now, so if anyone starts doing it, please let me know so I don’t duplicate the effort)