Skip to content

Commit

Permalink
fix JuliaLang#44086, missing field reordering in `NamedTuple{n,T}(::N…
Browse files Browse the repository at this point in the history
…amedTuple)` (JuliaLang#44132)
  • Loading branch information
JeffBezanson committed Feb 14, 2022
1 parent 17a4024 commit ed19129
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 2 deletions.
13 changes: 11 additions & 2 deletions base/namedtuple.jl
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,23 @@ if nameof(@__MODULE__) === :Base
$(Expr(:splatnew, :(NamedTuple{names,T}), :(T(args))))
end

function NamedTuple{names, T}(nt::NamedTuple) where {names, T <: Tuple}
if @generated
Expr(:new, :(NamedTuple{names, T}),
Any[ :(convert(fieldtype(T, $n), getfield(nt, $(QuoteNode(names[n]))))) for n in 1:length(names) ]...)
else
NamedTuple{names, T}(map(Fix1(getfield, nt), names))
end
end

function NamedTuple{names}(nt::NamedTuple) where {names}
if @generated
idx = Int[ fieldindex(nt, names[n]) for n in 1:length(names) ]
types = Tuple{(fieldtype(nt, idx[n]) for n in 1:length(idx))...}
Expr(:new, :(NamedTuple{names, $types}), Any[ :(getfield(nt, $(idx[n]))) for n in 1:length(idx) ]...)
else
types = Tuple{(fieldtype(typeof(nt), names[n]) for n in 1:length(names))...}
NamedTuple{names, types}(Tuple(getfield(nt, n) for n in 1:length(names)))
NamedTuple{names, types}(map(Fix1(getfield, nt), names))
end
end

Expand Down Expand Up @@ -339,7 +348,7 @@ function structdiff(a::NamedTuple{an}, b::Union{NamedTuple{bn}, Type{NamedTuple{
else
names = diff_names(an, bn)
types = Tuple{Any[ fieldtype(typeof(a), names[n]) for n in 1:length(names) ]...}
NamedTuple{names,types}(map(n->getfield(a, n), names))
NamedTuple{names,types}(map(Fix1(getfield, a), names))
end
end

Expand Down
3 changes: 3 additions & 0 deletions test/namedtuple.jl
Original file line number Diff line number Diff line change
Expand Up @@ -333,3 +333,6 @@ end

# issue #43045
@test merge(NamedTuple(), Iterators.reverse(pairs((a=1,b=2)))) === (b = 2, a = 1)

# issue #44086
@test NamedTuple{(:x, :y, :z), Tuple{Int8, Int16, Int32}}((z=1, x=2, y=3)) === (x = Int8(2), y = Int16(3), z = Int32(1))

0 comments on commit ed19129

Please sign in to comment.