@@ -405,8 +405,8 @@ use input::SplitGenerics;
405405use proc_macro2:: TokenStream ;
406406use quote:: { quote, quote_spanned, ToTokens } ;
407407use syn:: {
408- spanned:: Spanned , Attribute , DataEnum , DataStruct , DataUnion , DeriveInput , Expr , ExprLit ,
409- ExprPath , Fields , FieldsNamed , FieldsUnnamed , Lit , Meta , Path , Result , Variant ,
408+ spanned:: Spanned , Attribute , DataEnum , DataStruct , DataUnion , DeriveInput , Fields , FieldsNamed ,
409+ FieldsUnnamed , Meta , Path , Result , Variant ,
410410} ;
411411use util:: MetaListExt ;
412412
@@ -500,39 +500,11 @@ fn derive_where_internal(mut item: DeriveInput) -> Result<TokenStream> {
500500 let meta = nested. into_iter ( ) . next ( ) . expect ( "unexpected empty list" ) ;
501501
502502 if meta. path ( ) . is_ident ( "crate" ) {
503- if let Meta :: NameValue ( name_value) = meta {
504- let path = match & name_value. value {
505- Expr :: Lit ( ExprLit {
506- lit : Lit :: Str ( lit_str) ,
507- ..
508- } ) => match lit_str. parse :: < Path > ( ) {
509- Ok ( path) => path,
510- Err ( error) => {
511- return Err ( Error :: path ( lit_str. span ( ) , error) )
512- }
513- } ,
514- Expr :: Path ( ExprPath { path, .. } ) => path. clone ( ) ,
515- _ => return Err ( Error :: option_syntax ( name_value. value . span ( ) ) ) ,
516- } ;
517-
518- if path == util:: path_from_strs ( & [ DERIVE_WHERE ] ) {
519- return Err ( Error :: path_unnecessary (
520- path. span ( ) ,
521- & format ! ( "::{}" , DERIVE_WHERE ) ,
522- ) ) ;
523- }
524-
525- match crate_ {
526- Some ( _) => {
527- return Err ( Error :: option_duplicate (
528- name_value. span ( ) ,
529- "crate" ,
530- ) )
531- }
532- None => crate_ = Some ( path) ,
533- }
534- } else {
535- return Err ( Error :: option_syntax ( meta. span ( ) ) ) ;
503+ let ( path, span) = attr:: parse_crate ( meta) ?;
504+
505+ match crate_ {
506+ Some ( _) => return Err ( Error :: option_duplicate ( span, "crate" ) ) ,
507+ None => crate_ = Some ( path) ,
536508 }
537509 }
538510 }
@@ -573,7 +545,7 @@ fn derive_where_internal(mut item: DeriveInput) -> Result<TokenStream> {
573545#[ cfg_attr( feature = "nightly" , allow_internal_unstable( core_intrinsics) ) ]
574546pub fn derive_where_actual ( input : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
575547 let input = TokenStream :: from ( input) ;
576- let item = match syn:: parse2 :: < DeriveInput > ( input) {
548+ let full_item = match syn:: parse2 :: < DeriveInput > ( input) {
577549 Ok ( item) => item,
578550 Err ( error) => {
579551 return error. into_compile_error ( ) . into ( ) ;
@@ -583,24 +555,34 @@ pub fn derive_where_actual(input: proc_macro::TokenStream) -> proc_macro::TokenS
583555 let span = {
584556 let clean_item = DeriveInput {
585557 attrs : Vec :: new ( ) ,
586- vis : item . vis . clone ( ) ,
587- ident : item . ident . clone ( ) ,
588- generics : item . generics . clone ( ) ,
589- data : item . data . clone ( ) ,
558+ vis : full_item . vis . clone ( ) ,
559+ ident : full_item . ident . clone ( ) ,
560+ generics : full_item . generics . clone ( ) ,
561+ data : full_item . data . clone ( ) ,
590562 } ;
591563
592564 clean_item. span ( )
593565 } ;
594566
595- match Input :: from_input ( span, & item ) {
567+ match Input :: from_input ( span, & full_item ) {
596568 Ok ( Input {
569+ crate_,
597570 derive_wheres,
598571 generics,
599572 item,
600573 } ) => derive_wheres
601574 . iter ( )
602575 . flat_map ( |derive_where| iter:: repeat ( derive_where) . zip ( & derive_where. traits ) )
603- . map ( |( derive_where, trait_) | generate_impl ( derive_where, trait_, & item, & generics) )
576+ . map ( |( derive_where, trait_) | {
577+ generate_impl (
578+ crate_. as_ref ( ) ,
579+ & full_item,
580+ derive_where,
581+ trait_,
582+ & item,
583+ & generics,
584+ )
585+ } )
604586 . collect :: < TokenStream > ( )
605587 . into ( ) ,
606588 Err ( error) => error. into_compile_error ( ) . into ( ) ,
@@ -627,6 +609,8 @@ pub fn derive_where_visited(
627609
628610/// Generate implementation for a [`Trait`].
629611fn generate_impl (
612+ crate_ : Option < & Path > ,
613+ full_item : & DeriveInput ,
630614 derive_where : & DeriveWhere ,
631615 trait_ : & DeriveTrait ,
632616 item : & Item ,
@@ -643,7 +627,7 @@ fn generate_impl(
643627 let body = generate_body ( derive_where, trait_, item, generics) ;
644628
645629 let ident = item. ident ( ) ;
646- let mut output = trait_. impl_item ( imp, ident, ty, & where_clause, body) ;
630+ let mut output = trait_. impl_item ( crate_ , full_item , imp, ident, ty, & where_clause, body) ;
647631
648632 if let Some ( ( path, body) ) = trait_. additional_impl ( ) {
649633 output. extend ( quote ! {
@@ -734,3 +718,14 @@ fn input_without_derive_where_attributes(mut input: DeriveInput) -> DeriveInput
734718
735719 input
736720}
721+
722+ /// This is used by the Serde implementation to remove the duplicate item.
723+ #[ cfg( feature = "serde" ) ]
724+ #[ doc( hidden) ]
725+ #[ proc_macro_attribute]
726+ pub fn derive_where_serde (
727+ _: proc_macro:: TokenStream ,
728+ _: proc_macro:: TokenStream ,
729+ ) -> proc_macro:: TokenStream {
730+ proc_macro:: TokenStream :: new ( )
731+ }
0 commit comments