|  | 
| 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