@@ -797,7 +797,12 @@ pub struct Variant {
797797 other : bool ,
798798 serialize_with : Option < syn:: ExprPath > ,
799799 deserialize_with : Option < syn:: ExprPath > ,
800- borrow : Option < syn:: Meta > ,
800+ borrow : Option < BorrowAttribute > ,
801+ }
802+
803+ struct BorrowAttribute {
804+ path : syn:: Path ,
805+ lifetimes : Option < BTreeSet < syn:: Lifetime > > ,
801806}
802807
803808impl Variant {
@@ -950,10 +955,35 @@ impl Variant {
950955 }
951956 }
952957
953- // Defer `#[serde(borrow)]` and `#[serde(borrow = "'a + 'b")]`
954- Meta ( m) if m. path ( ) == BORROW => match & variant. fields {
958+ // Parse `#[serde(borrow)]`
959+ Meta ( Path ( word) ) if word == BORROW => match & variant. fields {
960+ syn:: Fields :: Unnamed ( fields) if fields. unnamed . len ( ) == 1 => {
961+ borrow. set (
962+ word,
963+ BorrowAttribute {
964+ path : word. clone ( ) ,
965+ lifetimes : None ,
966+ } ,
967+ ) ;
968+ }
969+ _ => {
970+ let msg = "#[serde(borrow)] may only be used on newtype variants" ;
971+ cx. error_spanned_by ( variant, msg) ;
972+ }
973+ } ,
974+
975+ // Parse `#[serde(borrow = "'a + 'b")]`
976+ Meta ( NameValue ( m) ) if m. path == BORROW => match & variant. fields {
955977 syn:: Fields :: Unnamed ( fields) if fields. unnamed . len ( ) == 1 => {
956- borrow. set ( m. path ( ) , m. clone ( ) ) ;
978+ if let Ok ( lifetimes) = parse_lit_into_lifetimes ( cx, BORROW , & m. lit ) {
979+ borrow. set (
980+ & m. path ,
981+ BorrowAttribute {
982+ path : m. path . clone ( ) ,
983+ lifetimes : Some ( lifetimes) ,
984+ } ,
985+ ) ;
986+ }
957987 }
958988 _ => {
959989 let msg = "#[serde(borrow)] may only be used on newtype variants" ;
@@ -1110,17 +1140,29 @@ impl Field {
11101140 None => index. to_string ( ) ,
11111141 } ;
11121142
1113- let variant_borrow = attrs
1114- . and_then ( |variant| variant. borrow . as_ref ( ) )
1115- . map ( |borrow| Meta ( borrow. clone ( ) ) ) ;
1116-
1117- for meta_item in variant_borrow. into_iter ( ) . chain (
1118- field
1119- . attrs
1120- . iter ( )
1121- . flat_map ( |attr| get_serde_meta_items ( cx, attr) )
1122- . flatten ( ) ,
1123- ) {
1143+ if let Some ( borrow_attribute) = attrs. and_then ( |variant| variant. borrow . as_ref ( ) ) {
1144+ if let Ok ( borrowable) = borrowable_lifetimes ( cx, & ident, field) {
1145+ if let Some ( lifetimes) = & borrow_attribute. lifetimes {
1146+ for lifetime in lifetimes {
1147+ if !borrowable. contains ( lifetime) {
1148+ let msg =
1149+ format ! ( "field `{}` does not have lifetime {}" , ident, lifetime) ;
1150+ cx. error_spanned_by ( field, msg) ;
1151+ }
1152+ }
1153+ borrowed_lifetimes. set ( & borrow_attribute. path , lifetimes. clone ( ) ) ;
1154+ } else {
1155+ borrowed_lifetimes. set ( & borrow_attribute. path , borrowable) ;
1156+ }
1157+ }
1158+ }
1159+
1160+ for meta_item in field
1161+ . attrs
1162+ . iter ( )
1163+ . flat_map ( |attr| get_serde_meta_items ( cx, attr) )
1164+ . flatten ( )
1165+ {
11241166 match & meta_item {
11251167 // Parse `#[serde(rename = "foo")]`
11261168 Meta ( NameValue ( m) ) if m. path == RENAME => {
0 commit comments