@@ -458,6 +458,7 @@ fn expand_simple_derive(
458458 invoc_span : Span ,
459459 tt : & tt:: TopSubtree ,
460460 trait_path : tt:: TopSubtree ,
461+ allow_unions : bool ,
461462 make_trait_body : impl FnOnce ( & BasicAdtInfo ) -> tt:: TopSubtree ,
462463) -> ExpandResult < tt:: TopSubtree > {
463464 let info = match parse_adt ( db, tt, invoc_span) {
@@ -469,6 +470,12 @@ fn expand_simple_derive(
469470 ) ;
470471 }
471472 } ;
473+ if !allow_unions && matches ! ( info. shape, AdtShape :: Union ) {
474+ return ExpandResult :: new (
475+ tt:: TopSubtree :: empty ( tt:: DelimSpan :: from_single ( invoc_span) ) ,
476+ ExpandError :: other ( invoc_span, "this trait cannot be derived for unions" ) ,
477+ ) ;
478+ }
472479 ExpandResult :: ok ( expand_simple_derive_with_parsed (
473480 invoc_span,
474481 info,
@@ -535,7 +542,14 @@ fn copy_expand(
535542 tt : & tt:: TopSubtree ,
536543) -> ExpandResult < tt:: TopSubtree > {
537544 let krate = dollar_crate ( span) ;
538- expand_simple_derive ( db, span, tt, quote ! { span => #krate:: marker:: Copy } , |_| quote ! { span =>} )
545+ expand_simple_derive (
546+ db,
547+ span,
548+ tt,
549+ quote ! { span => #krate:: marker:: Copy } ,
550+ true ,
551+ |_| quote ! { span =>} ,
552+ )
539553}
540554
541555fn clone_expand (
@@ -544,7 +558,7 @@ fn clone_expand(
544558 tt : & tt:: TopSubtree ,
545559) -> ExpandResult < tt:: TopSubtree > {
546560 let krate = dollar_crate ( span) ;
547- expand_simple_derive ( db, span, tt, quote ! { span => #krate:: clone:: Clone } , |adt| {
561+ expand_simple_derive ( db, span, tt, quote ! { span => #krate:: clone:: Clone } , true , |adt| {
548562 if matches ! ( adt. shape, AdtShape :: Union ) {
549563 let star = tt:: Punct { char : '*' , spacing : :: tt:: Spacing :: Alone , span } ;
550564 return quote ! { span =>
@@ -599,41 +613,63 @@ fn default_expand(
599613 tt : & tt:: TopSubtree ,
600614) -> ExpandResult < tt:: TopSubtree > {
601615 let krate = & dollar_crate ( span) ;
602- expand_simple_derive ( db, span, tt, quote ! { span => #krate:: default :: Default } , |adt| {
603- let body = match & adt. shape {
604- AdtShape :: Struct ( fields) => {
605- let name = & adt. name ;
606- fields. as_pattern_map (
607- quote ! ( span =>#name) ,
616+ let adt = match parse_adt ( db, tt, span) {
617+ Ok ( info) => info,
618+ Err ( e) => {
619+ return ExpandResult :: new (
620+ tt:: TopSubtree :: empty ( tt:: DelimSpan { open : span, close : span } ) ,
621+ e,
622+ ) ;
623+ }
624+ } ;
625+ let ( body, constrain_to_trait) = match & adt. shape {
626+ AdtShape :: Struct ( fields) => {
627+ let name = & adt. name ;
628+ let body = fields. as_pattern_map (
629+ quote ! ( span =>#name) ,
630+ span,
631+ |_| quote ! ( span =>#krate:: default :: Default :: default ( ) ) ,
632+ ) ;
633+ ( body, true )
634+ }
635+ AdtShape :: Enum { default_variant, variants } => {
636+ if let Some ( d) = default_variant {
637+ let ( name, fields) = & variants[ * d] ;
638+ let adt_name = & adt. name ;
639+ let body = fields. as_pattern_map (
640+ quote ! ( span =>#adt_name :: #name) ,
608641 span,
609642 |_| quote ! ( span =>#krate:: default :: Default :: default ( ) ) ,
610- )
643+ ) ;
644+ ( body, false )
645+ } else {
646+ return ExpandResult :: new (
647+ tt:: TopSubtree :: empty ( tt:: DelimSpan :: from_single ( span) ) ,
648+ ExpandError :: other ( span, "`#[derive(Default)]` on enum with no `#[default]`" ) ,
649+ ) ;
611650 }
612- AdtShape :: Enum { default_variant, variants } => {
613- if let Some ( d) = default_variant {
614- let ( name, fields) = & variants[ * d] ;
615- let adt_name = & adt. name ;
616- fields. as_pattern_map (
617- quote ! ( span =>#adt_name :: #name) ,
618- span,
619- |_| quote ! ( span =>#krate:: default :: Default :: default ( ) ) ,
620- )
621- } else {
622- // FIXME: Return expand error here
623- quote ! ( span =>)
651+ }
652+ AdtShape :: Union => {
653+ return ExpandResult :: new (
654+ tt:: TopSubtree :: empty ( tt:: DelimSpan :: from_single ( span) ) ,
655+ ExpandError :: other ( span, "this trait cannot be derived for unions" ) ,
656+ ) ;
657+ }
658+ } ;
659+ ExpandResult :: ok ( expand_simple_derive_with_parsed (
660+ span,
661+ adt,
662+ quote ! { span => #krate:: default :: Default } ,
663+ |_adt| {
664+ quote ! { span =>
665+ fn default ( ) -> Self {
666+ #body
624667 }
625668 }
626- AdtShape :: Union => {
627- // FIXME: Return expand error here
628- quote ! ( span =>)
629- }
630- } ;
631- quote ! { span =>
632- fn default ( ) -> Self {
633- #body
634- }
635- }
636- } )
669+ } ,
670+ constrain_to_trait,
671+ tt:: TopSubtree :: empty ( tt:: DelimSpan :: from_single ( span) ) ,
672+ ) )
637673}
638674
639675fn debug_expand (
@@ -642,7 +678,7 @@ fn debug_expand(
642678 tt : & tt:: TopSubtree ,
643679) -> ExpandResult < tt:: TopSubtree > {
644680 let krate = & dollar_crate ( span) ;
645- expand_simple_derive ( db, span, tt, quote ! { span => #krate:: fmt:: Debug } , |adt| {
681+ expand_simple_derive ( db, span, tt, quote ! { span => #krate:: fmt:: Debug } , false , |adt| {
646682 let for_variant = |name : String , v : & VariantShape | match v {
647683 VariantShape :: Struct ( fields) => {
648684 let for_fields = fields. iter ( ) . map ( |it| {
@@ -697,10 +733,7 @@ fn debug_expand(
697733 }
698734 } )
699735 . collect ( ) ,
700- AdtShape :: Union => {
701- // FIXME: Return expand error here
702- vec ! [ ]
703- }
736+ AdtShape :: Union => unreachable ! ( ) ,
704737 } ;
705738 quote ! { span =>
706739 fn fmt( & self , f: & mut #krate:: fmt:: Formatter ) -> #krate:: fmt:: Result {
@@ -718,11 +751,7 @@ fn hash_expand(
718751 tt : & tt:: TopSubtree ,
719752) -> ExpandResult < tt:: TopSubtree > {
720753 let krate = & dollar_crate ( span) ;
721- expand_simple_derive ( db, span, tt, quote ! { span => #krate:: hash:: Hash } , |adt| {
722- if matches ! ( adt. shape, AdtShape :: Union ) {
723- // FIXME: Return expand error here
724- return quote ! { span =>} ;
725- }
754+ expand_simple_derive ( db, span, tt, quote ! { span => #krate:: hash:: Hash } , false , |adt| {
726755 if matches ! ( & adt. shape, AdtShape :: Enum { variants, .. } if variants. is_empty( ) ) {
727756 let star = tt:: Punct { char : '*' , spacing : :: tt:: Spacing :: Alone , span } ;
728757 return quote ! { span =>
@@ -769,7 +798,14 @@ fn eq_expand(
769798 tt : & tt:: TopSubtree ,
770799) -> ExpandResult < tt:: TopSubtree > {
771800 let krate = dollar_crate ( span) ;
772- expand_simple_derive ( db, span, tt, quote ! { span => #krate:: cmp:: Eq } , |_| quote ! { span =>} )
801+ expand_simple_derive (
802+ db,
803+ span,
804+ tt,
805+ quote ! { span => #krate:: cmp:: Eq } ,
806+ true ,
807+ |_| quote ! { span =>} ,
808+ )
773809}
774810
775811fn partial_eq_expand (
@@ -778,11 +814,7 @@ fn partial_eq_expand(
778814 tt : & tt:: TopSubtree ,
779815) -> ExpandResult < tt:: TopSubtree > {
780816 let krate = dollar_crate ( span) ;
781- expand_simple_derive ( db, span, tt, quote ! { span => #krate:: cmp:: PartialEq } , |adt| {
782- if matches ! ( adt. shape, AdtShape :: Union ) {
783- // FIXME: Return expand error here
784- return quote ! { span =>} ;
785- }
817+ expand_simple_derive ( db, span, tt, quote ! { span => #krate:: cmp:: PartialEq } , false , |adt| {
786818 let name = & adt. name ;
787819
788820 let ( self_patterns, other_patterns) = self_and_other_patterns ( adt, name, span) ;
@@ -854,7 +886,7 @@ fn ord_expand(
854886 tt : & tt:: TopSubtree ,
855887) -> ExpandResult < tt:: TopSubtree > {
856888 let krate = & dollar_crate ( span) ;
857- expand_simple_derive ( db, span, tt, quote ! { span => #krate:: cmp:: Ord } , |adt| {
889+ expand_simple_derive ( db, span, tt, quote ! { span => #krate:: cmp:: Ord } , false , |adt| {
858890 fn compare (
859891 krate : & tt:: Ident ,
860892 left : tt:: TopSubtree ,
@@ -873,10 +905,6 @@ fn ord_expand(
873905 }
874906 }
875907 }
876- if matches ! ( adt. shape, AdtShape :: Union ) {
877- // FIXME: Return expand error here
878- return quote ! ( span =>) ;
879- }
880908 let ( self_patterns, other_patterns) = self_and_other_patterns ( adt, & adt. name , span) ;
881909 let arms = izip ! ( self_patterns, other_patterns, adt. shape. field_names( span) ) . map (
882910 |( pat1, pat2, fields) | {
@@ -916,7 +944,7 @@ fn partial_ord_expand(
916944 tt : & tt:: TopSubtree ,
917945) -> ExpandResult < tt:: TopSubtree > {
918946 let krate = & dollar_crate ( span) ;
919- expand_simple_derive ( db, span, tt, quote ! { span => #krate:: cmp:: PartialOrd } , |adt| {
947+ expand_simple_derive ( db, span, tt, quote ! { span => #krate:: cmp:: PartialOrd } , false , |adt| {
920948 fn compare (
921949 krate : & tt:: Ident ,
922950 left : tt:: TopSubtree ,
@@ -935,10 +963,6 @@ fn partial_ord_expand(
935963 }
936964 }
937965 }
938- if matches ! ( adt. shape, AdtShape :: Union ) {
939- // FIXME: Return expand error here
940- return quote ! ( span =>) ;
941- }
942966 let left = quote ! ( span =>#krate:: intrinsics:: discriminant_value( self ) ) ;
943967 let right = quote ! ( span =>#krate:: intrinsics:: discriminant_value( other) ) ;
944968
0 commit comments