From ed19129aa6b54bb3107b0413addcad34021723b9 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Mon, 14 Feb 2022 15:36:26 -0500 Subject: [PATCH] fix #44086, missing field reordering in `NamedTuple{n,T}(::NamedTuple)` (#44132) --- base/namedtuple.jl | 13 +++++++++++-- test/namedtuple.jl | 3 +++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/base/namedtuple.jl b/base/namedtuple.jl index d05ad6e10b544..050d460f24724 100644 --- a/base/namedtuple.jl +++ b/base/namedtuple.jl @@ -96,6 +96,15 @@ 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) ] @@ -103,7 +112,7 @@ function NamedTuple{names}(nt::NamedTuple) where {names} 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 @@ -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 diff --git a/test/namedtuple.jl b/test/namedtuple.jl index 3298a1c7a2562..3b571b3c7d612 100644 --- a/test/namedtuple.jl +++ b/test/namedtuple.jl @@ -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))