-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Closed
Labels
compiler:inferenceType inferenceType inference
Description
While looking into JuliaArrays/StructArrays.jl#3
Would be nice if this could work:
julia> struct Bar
a::Int
b::Float64
end
julia> foo(T, arg1, arg2) = NamedTuple{fieldnames(T)}((arg1, arg2))
foo (generic function with 1 method)
julia> foo(Bar, rand(Int, 2), rand(2))
(a = [4045710338091169239, -2764974619330172803], b = [0.6665, 0.404776])
julia> @code_warntype foo(Bar, rand(Int, 2), rand(2))
Body::Any
...
11 ─ %38 = (Core.apply_type)(Main.NamedTuple, %36)::Type{NamedTuple{_1,T} where T<:Tuple} where _1
│ %39 = (Core.tuple)(arg1, arg2)::Tuple{Array{Int64,1},Array{Float64,1}} │
│ %40 = (%38)(%39)::Any Using a @generated function makes it infer
julia> @generated function __fieldnames(t::Type{T}) where {T}
return :($(Expr(:tuple, [QuoteNode(f) for f in fieldnames(T)]...)))
end
__fieldnames (generic function with 2 methods)
julia> foo(T, arg1, arg2) = NamedTuple{__fieldnames(T)}((arg1, arg2))
foo (generic function with 1 method)
julia> @code_warntype foo(Bar, rand(Int, 2), rand(2))
Body::NamedTuple{(:a, :b),Tuple{Array{Int64,1},Array{Float64,1}}}
1 1 ─ %1 = %new(NamedTuple{(:a, :b),Tuple{Array{Int64,1},Array{Float64,1}}}, arg1, arg2)::NamedTuple{(:a, :b),Tuple{Array{Int64,1},Array{Float64,1}}}
└── return %1 Abusing pure makes it infer...
julia> Base.@pure _fieldnames(T) = fieldnames(T)
_fieldnames (generic function with 1 method)
julia> foo(T, arg1, arg2) = NamedTuple{_fieldnames(T)}((arg1, arg2))
foo (generic function with 1 method)
julia> @code_warntype foo(Bar, rand(Int, 2), rand(2))
Body::NamedTuple{(:a, :b),Tuple{Array{Int64,1},Array{Float64,1}}}
1 1 ─ invoke Main._fieldnames(_2::Type) │
│ %2 = %new(NamedTuple{(:a, :b),Tuple{Array{Int64,1},Array{Float64,1}}}, arg1, arg2)::NamedTuple{(:a, :b),Tuple{Array{Int64,1},Array{Float64,1}}}
└── return %2 Metadata
Metadata
Assignees
Labels
compiler:inferenceType inferenceType inference