@@ -126,6 +126,7 @@ impl Choice {
126126 ///
127127 /// This function only exists as an **escape hatch** for the rare case
128128 /// where it's not possible to use one of the `subtle`-provided
129+ /// where it's not possible to use one of the `subtle`-provided
129130 /// trait impls.
130131 ///
131132 /// **To convert a `Choice` to a `bool`, use the `From` implementation instead.**
@@ -383,14 +384,19 @@ impl ConstantTimeEq for cmp::Ordering {
383384 }
384385}
385386
387+ /// Marker trait for types whose [`Clone`] impl operates in constant-time.
388+ pub trait ConstantTimeClone : Clone { }
389+
390+ impl < T : Copy > ConstantTimeClone for T { }
391+
386392/// A type which can be conditionally selected in constant time.
387393///
388394/// This trait also provides generic implementations of conditional
389395/// assignment and conditional swaps.
390396//
391397// #[inline] is specified on these function prototypes to signify that they
392398#[ allow( unused_attributes) ] // should be in the actual implementation
393- pub trait ConditionallySelectable : Copy {
399+ pub trait ConditionallySelectable : ConstantTimeClone {
394400 /// Select `a` or `b` according to `choice`.
395401 ///
396402 /// # Returns
@@ -467,7 +473,7 @@ pub trait ConditionallySelectable: Copy {
467473 /// ```
468474 #[ inline]
469475 fn conditional_swap ( a : & mut Self , b : & mut Self , choice : Choice ) {
470- let t: Self = * a ;
476+ let t: Self = a . clone ( ) ;
471477 a. conditional_assign ( & b, choice) ;
472478 b. conditional_assign ( & t, choice) ;
473479 }
@@ -575,7 +581,7 @@ impl ConditionallySelectable for Choice {
575581#[ cfg( feature = "const-generics" ) ]
576582impl < T , const N : usize > ConditionallySelectable for [ T ; N ]
577583where
578- T : ConditionallySelectable ,
584+ T : ConditionallySelectable + Copy ,
579585{
580586 #[ inline]
581587 fn conditional_select ( a : & Self , b : & Self , choice : Choice ) -> Self {
@@ -741,49 +747,34 @@ impl<T> CtOption<T> {
741747
742748 /// Returns a `None` value if the option is `None`, otherwise
743749 /// returns a `CtOption` enclosing the value of the provided closure.
744- /// The closure is given the enclosed value or, if the option is
745- /// `None`, it is provided a dummy value computed using
746- /// `Default::default()`.
750+ /// The closure is given the enclosed value.
747751 ///
748752 /// This operates in constant time, because the provided closure
749753 /// is always called.
750754 #[ inline]
751755 pub fn map < U , F > ( self , f : F ) -> CtOption < U >
752756 where
753- T : Default + ConditionallySelectable ,
757+ T : ConditionallySelectable ,
754758 F : FnOnce ( T ) -> U ,
755759 {
756- CtOption :: new (
757- f ( T :: conditional_select (
758- & T :: default ( ) ,
759- & self . value ,
760- self . is_some ,
761- ) ) ,
762- self . is_some ,
763- )
760+ CtOption :: new ( f ( self . value ) , self . is_some )
764761 }
765762
766763 /// Returns a `None` value if the option is `None`, otherwise
767764 /// returns the result of the provided closure. The closure is
768- /// given the enclosed value or, if the option is `None`, it
769- /// is provided a dummy value computed using `Default::default()`.
765+ /// given the enclosed value.
770766 ///
771767 /// This operates in constant time, because the provided closure
772768 /// is always called.
773769 #[ inline]
774770 pub fn and_then < U , F > ( self , f : F ) -> CtOption < U >
775771 where
776- T : Default + ConditionallySelectable ,
772+ T : ConditionallySelectable ,
777773 F : FnOnce ( T ) -> CtOption < U > ,
778774 {
779- let mut tmp = f ( T :: conditional_select (
780- & T :: default ( ) ,
781- & self . value ,
782- self . is_some ,
783- ) ) ;
784- tmp. is_some &= self . is_some ;
785-
786- tmp
775+ let mut ret = f ( self . value ) ;
776+ ret. is_some &= self . is_some ;
777+ ret
787778 }
788779
789780 /// Returns `self` if it contains a value, and otherwise returns the result of
@@ -797,7 +788,10 @@ impl<T> CtOption<T> {
797788 let is_none = self . is_none ( ) ;
798789 let f = f ( ) ;
799790
800- Self :: conditional_select ( & self , & f, is_none)
791+ CtOption :: new (
792+ T :: conditional_select ( & self . value , & f. value , is_none) ,
793+ Choice :: conditional_select ( & self . is_some , & f. is_some , is_none) ,
794+ )
801795 }
802796
803797 /// Convert the `CtOption<T>` wrapper into an `Option<T>`, depending on whether
@@ -817,7 +811,10 @@ impl<T> CtOption<T> {
817811 }
818812}
819813
820- impl < T : ConditionallySelectable > ConditionallySelectable for CtOption < T > {
814+ impl < T > ConditionallySelectable for CtOption < T >
815+ where
816+ T : ConditionallySelectable + Copy
817+ {
821818 fn conditional_select ( a : & Self , b : & Self , choice : Choice ) -> Self {
822819 CtOption :: new (
823820 T :: conditional_select ( & a. value , & b. value , choice) ,
0 commit comments