diff --git a/src/ConstructionBase.jl b/src/ConstructionBase.jl index 293858e..c6dfba6 100644 --- a/src/ConstructionBase.jl +++ b/src/ConstructionBase.jl @@ -72,6 +72,19 @@ T{Int64,Int64}(10, 2) getfield(parentmodule(T), nameof(T)) end +constructorof(::Type{<:Tuple}) = tuple +constructorof(::Type{<:NamedTuple{names}}) where names = + NamedTupleConstructor{names}() + +struct NamedTupleConstructor{names} end + +@generated function (::NamedTupleConstructor{names})(args...) where names + quote + Base.@_inline_meta + $(NamedTuple{names, Tuple{args...}})(args) + end +end + function assert_hasfields(T, fnames) for fname in fnames if !(fname in fieldnames(T)) @@ -150,15 +163,5 @@ end ) end -@generated function setproperties(obj::NamedTuple, patch::NamedTuple) - # this function is only generated to force the following check - # at compile time - assert_hasfields(obj, fieldnames(patch)) - Expr(:block, - Expr(:meta, :inline), - :(merge(obj, patch)) - ) -end - end # module diff --git a/test/runtests.jl b/test/runtests.jl index b46b4da..42e3dfb 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -12,6 +12,10 @@ end @inferred constructorof(AB{Int, Int}) @test constructorof(AB{Int, Int})(1, 2) === AB(1,2) @test constructorof(AB{Int, Int})(1.0, 2) === AB(1.0,2) + @test constructorof(typeof((a=1, b=2)))(1.0, 2) === (a=1.0, b=2) + @test constructorof(NamedTuple{(:a, :b)})(1.0, 2) === (a=1.0, b=2) + @test constructorof(Tuple)(1.0, 2) === (1.0, 2) + @test constructorof(Tuple{Nothing, Missing})(1.0, 2) === (1.0, 2) end @testset "setproperties" begin