11use proc_macro2:: { Literal , TokenStream } ;
2+ use syn:: spanned:: Spanned ;
23use synstructure:: BindStyle ;
34
45use crate :: hygiene:: Hygiene ;
@@ -34,7 +35,7 @@ pub(crate) fn update_derive(input: syn::DeriveInput) -> syn::Result<TokenStream>
3435 . bindings ( )
3536 . iter ( )
3637 . fold ( quote ! ( ) , |tokens, binding| quote ! ( #tokens #binding, ) ) ;
37- let make_new_value = quote ! {
38+ let make_new_value = quote_spanned ! { variant . ast ( ) . ident . span ( ) =>
3839 let #new_value = if let #variant_pat = #new_value {
3940 ( #make_tuple)
4041 } else {
@@ -46,20 +47,28 @@ pub(crate) fn update_derive(input: syn::DeriveInput) -> syn::Result<TokenStream>
4647 // For each field, invoke `maybe_update` recursively to update its value.
4748 // Or the results together (using `|`, not `||`, to avoid shortcircuiting)
4849 // to get the final return value.
49- let update_fields = variant. bindings ( ) . iter ( ) . zip ( 0 .. ) . fold (
50+ let update_fields = variant. bindings ( ) . iter ( ) . enumerate ( ) . fold (
5051 quote ! ( false ) ,
51- |tokens, ( binding , index ) | {
52+ |tokens, ( index , binding ) | {
5253 let field_ty = & binding. ast ( ) . ty ;
5354 let field_index = Literal :: usize_unsuffixed ( index) ;
5455
56+ let field_span = binding
57+ . ast ( )
58+ . ident
59+ . as_ref ( )
60+ . map ( Spanned :: span)
61+ . unwrap_or ( binding. ast ( ) . span ( ) ) ;
62+
63+ let update_field = quote_spanned ! { field_span=>
64+ salsa:: plumbing:: UpdateDispatch :: <#field_ty>:: maybe_update(
65+ #binding,
66+ #new_value. #field_index,
67+ )
68+ } ;
69+
5570 quote ! {
56- #tokens |
57- unsafe {
58- salsa:: plumbing:: UpdateDispatch :: <#field_ty>:: maybe_update(
59- #binding,
60- #new_value. #field_index,
61- )
62- }
71+ #tokens | unsafe { #update_field }
6372 }
6473 } ,
6574 ) ;
@@ -77,6 +86,7 @@ pub(crate) fn update_derive(input: syn::DeriveInput) -> syn::Result<TokenStream>
7786 let ( impl_generics, ty_generics, where_clause) = input. generics . split_for_impl ( ) ;
7887 let tokens = quote ! {
7988 #[ allow( clippy:: all) ]
89+ #[ automatically_derived]
8090 unsafe impl #impl_generics salsa:: Update for #ident #ty_generics #where_clause {
8191 unsafe fn maybe_update( #old_pointer: * mut Self , #new_value: Self ) -> bool {
8292 use :: salsa:: plumbing:: UpdateFallback as _;
0 commit comments