@@ -458,6 +458,7 @@ fn expand_simple_derive(
458
458
invoc_span : Span ,
459
459
tt : & tt:: TopSubtree ,
460
460
trait_path : tt:: TopSubtree ,
461
+ allow_unions : bool ,
461
462
make_trait_body : impl FnOnce ( & BasicAdtInfo ) -> tt:: TopSubtree ,
462
463
) -> ExpandResult < tt:: TopSubtree > {
463
464
let info = match parse_adt ( db, tt, invoc_span) {
@@ -469,6 +470,12 @@ fn expand_simple_derive(
469
470
) ;
470
471
}
471
472
} ;
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
+ }
472
479
ExpandResult :: ok ( expand_simple_derive_with_parsed (
473
480
invoc_span,
474
481
info,
@@ -535,7 +542,14 @@ fn copy_expand(
535
542
tt : & tt:: TopSubtree ,
536
543
) -> ExpandResult < tt:: TopSubtree > {
537
544
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
+ )
539
553
}
540
554
541
555
fn clone_expand (
@@ -544,7 +558,7 @@ fn clone_expand(
544
558
tt : & tt:: TopSubtree ,
545
559
) -> ExpandResult < tt:: TopSubtree > {
546
560
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| {
548
562
if matches ! ( adt. shape, AdtShape :: Union ) {
549
563
let star = tt:: Punct { char : '*' , spacing : :: tt:: Spacing :: Alone , span } ;
550
564
return quote ! { span =>
@@ -599,41 +613,63 @@ fn default_expand(
599
613
tt : & tt:: TopSubtree ,
600
614
) -> ExpandResult < tt:: TopSubtree > {
601
615
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) ,
608
641
span,
609
642
|_| 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
+ ) ;
611
650
}
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
624
667
}
625
668
}
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
+ ) )
637
673
}
638
674
639
675
fn debug_expand (
@@ -642,7 +678,7 @@ fn debug_expand(
642
678
tt : & tt:: TopSubtree ,
643
679
) -> ExpandResult < tt:: TopSubtree > {
644
680
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| {
646
682
let for_variant = |name : String , v : & VariantShape | match v {
647
683
VariantShape :: Struct ( fields) => {
648
684
let for_fields = fields. iter ( ) . map ( |it| {
@@ -697,10 +733,7 @@ fn debug_expand(
697
733
}
698
734
} )
699
735
. collect ( ) ,
700
- AdtShape :: Union => {
701
- // FIXME: Return expand error here
702
- vec ! [ ]
703
- }
736
+ AdtShape :: Union => unreachable ! ( ) ,
704
737
} ;
705
738
quote ! { span =>
706
739
fn fmt( & self , f: & mut #krate:: fmt:: Formatter ) -> #krate:: fmt:: Result {
@@ -718,11 +751,7 @@ fn hash_expand(
718
751
tt : & tt:: TopSubtree ,
719
752
) -> ExpandResult < tt:: TopSubtree > {
720
753
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| {
726
755
if matches ! ( & adt. shape, AdtShape :: Enum { variants, .. } if variants. is_empty( ) ) {
727
756
let star = tt:: Punct { char : '*' , spacing : :: tt:: Spacing :: Alone , span } ;
728
757
return quote ! { span =>
@@ -769,7 +798,14 @@ fn eq_expand(
769
798
tt : & tt:: TopSubtree ,
770
799
) -> ExpandResult < tt:: TopSubtree > {
771
800
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
+ )
773
809
}
774
810
775
811
fn partial_eq_expand (
@@ -778,11 +814,7 @@ fn partial_eq_expand(
778
814
tt : & tt:: TopSubtree ,
779
815
) -> ExpandResult < tt:: TopSubtree > {
780
816
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| {
786
818
let name = & adt. name ;
787
819
788
820
let ( self_patterns, other_patterns) = self_and_other_patterns ( adt, name, span) ;
@@ -854,7 +886,7 @@ fn ord_expand(
854
886
tt : & tt:: TopSubtree ,
855
887
) -> ExpandResult < tt:: TopSubtree > {
856
888
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| {
858
890
fn compare (
859
891
krate : & tt:: Ident ,
860
892
left : tt:: TopSubtree ,
@@ -873,10 +905,6 @@ fn ord_expand(
873
905
}
874
906
}
875
907
}
876
- if matches ! ( adt. shape, AdtShape :: Union ) {
877
- // FIXME: Return expand error here
878
- return quote ! ( span =>) ;
879
- }
880
908
let ( self_patterns, other_patterns) = self_and_other_patterns ( adt, & adt. name , span) ;
881
909
let arms = izip ! ( self_patterns, other_patterns, adt. shape. field_names( span) ) . map (
882
910
|( pat1, pat2, fields) | {
@@ -916,7 +944,7 @@ fn partial_ord_expand(
916
944
tt : & tt:: TopSubtree ,
917
945
) -> ExpandResult < tt:: TopSubtree > {
918
946
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| {
920
948
fn compare (
921
949
krate : & tt:: Ident ,
922
950
left : tt:: TopSubtree ,
@@ -935,10 +963,6 @@ fn partial_ord_expand(
935
963
}
936
964
}
937
965
}
938
- if matches ! ( adt. shape, AdtShape :: Union ) {
939
- // FIXME: Return expand error here
940
- return quote ! ( span =>) ;
941
- }
942
966
let left = quote ! ( span =>#krate:: intrinsics:: discriminant_value( self ) ) ;
943
967
let right = quote ! ( span =>#krate:: intrinsics:: discriminant_value( other) ) ;
944
968
0 commit comments