@@ -77,14 +77,27 @@ backing(x::Tuple) = x
7777backing (x:: NamedTuple ) = x
7878backing (x:: Composite ) = getfield (x, :backing )
7979
80- @generated function backing (x):: NamedTuple
81- ! isstructtype (x) && throw (DomainError (x, " backing can only be use on composite types" ))
82- nfields = fieldcount (x)
83- names = ntuple (ii-> fieldname (x, ii), nfields)
84- types = ntuple (ii-> fieldtype (x, ii), nfields)
85-
86- vals = Expr (:tuple , ntuple (ii-> :(getfield (x, $ ii)), nfields)... )
87- return :(NamedTuple {$names, Tuple{$(types...)}} ($ vals))
80+ function backing (x:: T ):: NamedTuple where T
81+ # note: all computation outside the if @generated happens at runtime.
82+ # so the first 4 lines of the branchs look the same, but can not be moved out.
83+ # see https://github.com/JuliaLang/julia/issues/34283
84+ if @generated
85+ ! isstructtype (T) && throw (DomainError (T, " backing can only be use on composite types" ))
86+ nfields = fieldcount (T)
87+ names = fieldnames (T)
88+ types = fieldtypes (T)
89+
90+ vals = Expr (:tuple , ntuple (ii-> :(getfield (x, $ ii)), nfields)... )
91+ return :(NamedTuple {$names, Tuple{$(types...)}} ($ vals))
92+ else
93+ ! isstructtype (T) && throw (DomainError (T, " backing can only be use on composite types" ))
94+ nfields = fieldcount (T)
95+ names = fieldnames (T)
96+ types = fieldtypes (T)
97+
98+ vals = ntuple (ii-> getfield (x, ii), nfields)
99+ return NamedTuple {names, Tuple{types...}} (vals)
100+ end
88101end
89102
90103"""
0 commit comments