11use  crate :: attributes:: { self ,  get_pyo3_options,  CrateAttribute } ; 
22use  crate :: utils:: Ctx ; 
33use  proc_macro2:: { Span ,  TokenStream } ; 
4- use  quote:: { format_ident,  quote} ; 
4+ use  quote:: { format_ident,  quote,  quote_spanned } ; 
55use  syn:: ext:: IdentExt ; 
66use  syn:: parse:: { Parse ,  ParseStream } ; 
77use  syn:: spanned:: Spanned  as  _; 
@@ -81,9 +81,12 @@ struct IntoPyObjectImpl {
8181
8282struct  NamedStructField < ' a >  { 
8383    ident :  & ' a  syn:: Ident , 
84+     field :  & ' a  syn:: Field , 
8485} 
8586
86- struct  TupleStructField  { } 
87+ struct  TupleStructField < ' a >  { 
88+     field :  & ' a  syn:: Field , 
89+ } 
8790
8891/// Container Style 
8992/// 
@@ -101,7 +104,7 @@ enum ContainerType<'a> {
101104     /// 
102105     /// Variant contains a list of conversion methods for each of the fields that are directly 
103106     ///  extracted from the tuple. 
104-      Tuple ( Vec < TupleStructField > ) , 
107+      Tuple ( Vec < TupleStructField < ' a > > ) , 
105108    /// Tuple newtype, e.g. `#[transparent] struct Foo(String)` 
106109     /// 
107110     /// The wrapped field is directly extracted from the object. 
@@ -142,7 +145,7 @@ impl<'a> Container<'a> {
142145                    let  tuple_fields = unnamed
143146                        . unnamed 
144147                        . iter ( ) 
145-                         . map ( |_field | Ok ( TupleStructField  { } ) ) 
148+                         . map ( |field | Ok ( TupleStructField  {  field  } ) ) 
146149                        . collect :: < Result < Vec < _ > > > ( ) ?; 
147150
148151                    ContainerType :: Tuple ( tuple_fields) 
@@ -167,7 +170,7 @@ impl<'a> Container<'a> {
167170                                . as_ref ( ) 
168171                                . expect ( "Named fields should have identifiers" ) ; 
169172
170-                             Ok ( NamedStructField  {  ident } ) 
173+                             Ok ( NamedStructField  {  ident,  field  } ) 
171174                        } ) 
172175                        . collect :: < Result < Vec < _ > > > ( ) ?; 
173176                    ContainerType :: Struct ( struct_fields) 
@@ -241,7 +244,7 @@ impl<'a> Container<'a> {
241244            target :  quote !  { <#ty as  #pyo3_path:: conversion:: IntoPyObject <' py>>:: Target } , 
242245            output :  quote !  { <#ty as  #pyo3_path:: conversion:: IntoPyObject <' py>>:: Output } , 
243246            error :  quote !  { <#ty as  #pyo3_path:: conversion:: IntoPyObject <' py>>:: Error } , 
244-             body :  quote !  { 
247+             body :  quote_spanned !  {  ty . span ( )  => 
245248                #unpack
246249                <#ty as  #pyo3_path:: conversion:: IntoPyObject <' py>>:: into_pyobject( arg0,  py) 
247250            } , 
@@ -265,7 +268,7 @@ impl<'a> Container<'a> {
265268            . enumerate ( ) 
266269            . map ( |( i,  f) | { 
267270                let  key = f. ident . unraw ( ) . to_string ( ) ; 
268-                 let  value = format_ident ! ( "arg{i}" ) ; 
271+                 let  value = Ident :: new ( & format ! ( "arg{i}" ) ,  f . field . ty . span ( ) ) ; 
269272                quote !  { 
270273                    #pyo3_path:: types:: PyDictMethods :: set_item( & dict,  #key,  #value) ?; 
271274                } 
@@ -285,7 +288,7 @@ impl<'a> Container<'a> {
285288        } 
286289    } 
287290
288-     fn  build_tuple_struct ( & self ,  fields :  & [ TupleStructField ] ,  ctx :  & Ctx )  -> IntoPyObjectImpl  { 
291+     fn  build_tuple_struct ( & self ,  fields :  & [ TupleStructField < ' _ > ] ,  ctx :  & Ctx )  -> IntoPyObjectImpl  { 
289292        let  Ctx  {  pyo3_path,  .. }  = ctx; 
290293
291294        let  unpack = self 
@@ -300,10 +303,11 @@ impl<'a> Container<'a> {
300303        let  setter = fields
301304            . iter ( ) 
302305            . enumerate ( ) 
303-             . map ( |( i,  _) | { 
304-                 let  value = format_ident ! ( "arg{i}" ) ; 
305-                 quote !  { 
306-                     #pyo3_path:: conversion:: IntoPyObject :: into_pyobject( #value,  py) 
306+             . map ( |( i,  f) | { 
307+                 let  ty = & f. field . ty ; 
308+                 let  value = Ident :: new ( & format ! ( "arg{i}" ) ,  f. field . ty . span ( ) ) ; 
309+                 quote_spanned !  {  f. field. ty. span( )  =>
310+                     <#ty as  #pyo3_path:: conversion:: IntoPyObject >:: into_pyobject( #value,  py) 
307311                        . map( #pyo3_path:: BoundObject :: into_any) 
308312                        . map( #pyo3_path:: BoundObject :: into_bound) ?, 
309313                } 
0 commit comments