| 
151 | 151 | use std::cmp::{self, max, min, Ordering};  | 
152 | 152 | use std::fmt;  | 
153 | 153 | use std::iter::once;  | 
 | 154 | +use std::mem;  | 
154 | 155 | 
 
  | 
155 | 156 | use smallvec::SmallVec;  | 
156 | 157 | 
 
  | 
@@ -648,8 +649,6 @@ impl OpaqueId {  | 
648 | 649 | /// `specialize_constructor` returns the list of fields corresponding to a pattern, given a  | 
649 | 650 | /// constructor. `Constructor::apply` reconstructs the pattern from a pair of `Constructor` and  | 
650 | 651 | /// `Fields`.  | 
651 |  | -#[derive(derivative::Derivative)]  | 
652 |  | -#[derivative(Debug(bound = ""), Clone(bound = ""), PartialEq(bound = ""))]  | 
653 | 652 | pub enum Constructor<Cx: TypeCx> {  | 
654 | 653 |     /// Tuples and structs.  | 
655 | 654 |     Struct,  | 
@@ -692,6 +691,101 @@ pub enum Constructor<Cx: TypeCx> {  | 
692 | 691 |     Missing,  | 
693 | 692 | }  | 
694 | 693 | 
 
  | 
 | 694 | +impl<Cx: TypeCx> Clone for Constructor<Cx> {  | 
 | 695 | +    fn clone(&self) -> Self {  | 
 | 696 | +        match self {  | 
 | 697 | +            Constructor::Struct => Constructor::Struct,  | 
 | 698 | +            Constructor::Variant(idx) => Constructor::Variant(idx.clone()),  | 
 | 699 | +            Constructor::Ref => Constructor::Ref,  | 
 | 700 | +            Constructor::Slice(slice) => Constructor::Slice(slice.clone()),  | 
 | 701 | +            Constructor::UnionField => Constructor::UnionField,  | 
 | 702 | +            Constructor::Bool(b) => Constructor::Bool(b.clone()),  | 
 | 703 | +            Constructor::IntRange(range) => Constructor::IntRange(range.clone()),  | 
 | 704 | +            Constructor::F32Range(lo, hi, end) => {  | 
 | 705 | +                Constructor::F32Range(lo.clone(), hi.clone(), end.clone())  | 
 | 706 | +            }  | 
 | 707 | +            Constructor::F64Range(lo, hi, end) => {  | 
 | 708 | +                Constructor::F64Range(lo.clone(), hi.clone(), end.clone())  | 
 | 709 | +            }  | 
 | 710 | +            Constructor::Str(value) => Constructor::Str(value.clone()),  | 
 | 711 | +            Constructor::Opaque(inner) => Constructor::Opaque(inner.clone()),  | 
 | 712 | +            Constructor::Or => Constructor::Or,  | 
 | 713 | +            Constructor::Wildcard => Constructor::Wildcard,  | 
 | 714 | +            Constructor::NonExhaustive => Constructor::NonExhaustive,  | 
 | 715 | +            Constructor::Hidden => Constructor::Hidden,  | 
 | 716 | +            Constructor::Missing => Constructor::Missing,  | 
 | 717 | +        }  | 
 | 718 | +    }  | 
 | 719 | +}  | 
 | 720 | + | 
 | 721 | +impl<Cx: TypeCx> fmt::Debug for Constructor<Cx> {  | 
 | 722 | +    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {  | 
 | 723 | +        match self {  | 
 | 724 | +            Constructor::Struct => f.debug_tuple("Struct").finish(),  | 
 | 725 | +            Constructor::Variant(idx) => f.debug_tuple("Variant").field(idx).finish(),  | 
 | 726 | +            Constructor::Ref => f.debug_tuple("Ref").finish(),  | 
 | 727 | +            Constructor::Slice(slice) => f.debug_tuple("Slice").field(slice).finish(),  | 
 | 728 | +            Constructor::UnionField => f.debug_tuple("UnionField").finish(),  | 
 | 729 | +            Constructor::Bool(b) => f.debug_tuple("Bool").field(b).finish(),  | 
 | 730 | +            Constructor::IntRange(range) => f.debug_tuple("IntRange").field(range).finish(),  | 
 | 731 | +            Constructor::F32Range(lo, hi, end) => {  | 
 | 732 | +                f.debug_tuple("F32Range").field(lo).field(hi).field(end).finish()  | 
 | 733 | +            }  | 
 | 734 | +            Constructor::F64Range(lo, hi, end) => {  | 
 | 735 | +                f.debug_tuple("F64Range").field(lo).field(hi).field(end).finish()  | 
 | 736 | +            }  | 
 | 737 | +            Constructor::Str(value) => f.debug_tuple("Str").field(value).finish(),  | 
 | 738 | +            Constructor::Opaque(inner) => f.debug_tuple("Opaque").field(inner).finish(),  | 
 | 739 | +            Constructor::Or => f.debug_tuple("Or").finish(),  | 
 | 740 | +            Constructor::Wildcard => f.debug_tuple("Wildcard").finish(),  | 
 | 741 | +            Constructor::NonExhaustive => f.debug_tuple("NonExhaustive").finish(),  | 
 | 742 | +            Constructor::Hidden => f.debug_tuple("Hidden").finish(),  | 
 | 743 | +            Constructor::Missing => f.debug_tuple("Missing").finish(),  | 
 | 744 | +        }  | 
 | 745 | +    }  | 
 | 746 | +}  | 
 | 747 | + | 
 | 748 | +impl<Cx: TypeCx> PartialEq for Constructor<Cx> {  | 
 | 749 | +    fn eq(&self, other: &Self) -> bool {  | 
 | 750 | +        (mem::discriminant(self) == mem::discriminant(other))  | 
 | 751 | +            && match (self, other) {  | 
 | 752 | +                (Constructor::Struct, Constructor::Struct) => true,  | 
 | 753 | +                (Constructor::Variant(self_variant), Constructor::Variant(other_variant)) => {  | 
 | 754 | +                    self_variant == other_variant  | 
 | 755 | +                }  | 
 | 756 | +                (Constructor::Ref, Constructor::Ref) => true,  | 
 | 757 | +                (Constructor::Slice(self_slice), Constructor::Slice(other_slice)) => {  | 
 | 758 | +                    self_slice == other_slice  | 
 | 759 | +                }  | 
 | 760 | +                (Constructor::UnionField, Constructor::UnionField) => true,  | 
 | 761 | +                (Constructor::Bool(self_b), Constructor::Bool(other_b)) => self_b == other_b,  | 
 | 762 | +                (Constructor::IntRange(self_range), Constructor::IntRange(other_range)) => {  | 
 | 763 | +                    self_range == other_range  | 
 | 764 | +                }  | 
 | 765 | +                (  | 
 | 766 | +                    Constructor::F32Range(self_lo, self_hi, self_end),  | 
 | 767 | +                    Constructor::F32Range(other_lo, other_hi, other_end),  | 
 | 768 | +                ) => self_lo == other_lo && self_hi == other_hi && self_end == other_end,  | 
 | 769 | +                (  | 
 | 770 | +                    Constructor::F64Range(self_lo, self_hi, self_end),  | 
 | 771 | +                    Constructor::F64Range(other_lo, other_hi, other_end),  | 
 | 772 | +                ) => self_lo == other_lo && self_hi == other_hi && self_end == other_end,  | 
 | 773 | +                (Constructor::Str(self_value), Constructor::Str(other_value)) => {  | 
 | 774 | +                    self_value == other_value  | 
 | 775 | +                }  | 
 | 776 | +                (Constructor::Opaque(self_inner), Constructor::Opaque(other_inner)) => {  | 
 | 777 | +                    self_inner == other_inner  | 
 | 778 | +                }  | 
 | 779 | +                (Constructor::Or, Constructor::Or) => true,  | 
 | 780 | +                (Constructor::Wildcard, Constructor::Wildcard) => true,  | 
 | 781 | +                (Constructor::NonExhaustive, Constructor::NonExhaustive) => true,  | 
 | 782 | +                (Constructor::Hidden, Constructor::Hidden) => true,  | 
 | 783 | +                (Constructor::Missing, Constructor::Missing) => true,  | 
 | 784 | +                _ => unreachable!(),  | 
 | 785 | +            }  | 
 | 786 | +    }  | 
 | 787 | +}  | 
 | 788 | + | 
695 | 789 | impl<Cx: TypeCx> Constructor<Cx> {  | 
696 | 790 |     pub(crate) fn is_non_exhaustive(&self) -> bool {  | 
697 | 791 |         matches!(self, NonExhaustive)  | 
 | 
0 commit comments