Skip to content

Commit efbd650

Browse files
committed
Add Discriminant::unstable_cmp
Provides an unstable ordering between `Discriminant<T>` values.
1 parent d64de46 commit efbd650

2 files changed

Lines changed: 46 additions & 1 deletion

File tree

‎library/core/src/marker.rs‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,17 @@ pub trait DiscriminantKind {
884884
/// The type of the discriminant, which must satisfy the trait
885885
/// bounds required by `mem::Discriminant`.
886886
#[lang = "discriminant_type"]
887-
type Discriminant: Clone + Copy + Debug + Eq + PartialEq + Hash + Send + Sync + Unpin;
887+
type Discriminant: Clone
888+
+ Copy
889+
+ Debug
890+
+ Eq
891+
+ Hash
892+
+ Ord
893+
+ PartialEq
894+
+ PartialOrd
895+
+ Send
896+
+ Sync
897+
+ Unpin;
888898
}
889899

890900
/// Used to determine whether a type contains

‎library/core/src/mem/mod.rs‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,6 +1325,41 @@ impl<T> fmt::Debug for Discriminant<T> {
13251325
}
13261326
}
13271327

1328+
impl<T> Discriminant<T> {
1329+
/// Returns the *unstable* ordering between `self` and `other`.
1330+
///
1331+
/// [`Discriminant`] does not implement [`Ord`] as we do not guarantee a stable
1332+
/// ordering of discriminant values.
1333+
/// This will _typically_ sort enum variants by their declaration order, but
1334+
/// this is *not* guaranteed.
1335+
/// Likewise, non-enum values (e.g., `struct`s) will _typically_ be trivially
1336+
/// ordered as equivalent.
1337+
///
1338+
/// Users of this function should instead rely on the [`Ord`] implementation
1339+
/// of `T` wherever possible.
1340+
///
1341+
/// # Examples
1342+
///
1343+
/// ```
1344+
/// use std::cmp::Ordering;
1345+
/// use std::mem::discriminant;
1346+
///
1347+
/// enum Foo { A(i32), B(i32) }
1348+
///
1349+
/// // Equivalent arms will compare equal regardless of contained data
1350+
/// assert_eq!(discriminant(&Foo::A(1)).unstable_cmp(discriminant(&Foo::A(2))), Ordering::Equal);
1351+
///
1352+
/// // Inequivalent arms will compare not-equal
1353+
/// assert_ne!(discriminant(&Foo::A(1)).unstable_cmp(discriminant(&Foo::B(1))), Ordering::Equal);
1354+
/// ```
1355+
#[unstable(feature = "discriminant_cmp", issue = "none", reason = "not yet created")]
1356+
#[must_use]
1357+
#[inline]
1358+
pub fn unstable_cmp(&self, other: &Self) -> Ordering {
1359+
<<T as DiscriminantKind>::Discriminant as Ord>::cmp(&self.0, &other.0)
1360+
}
1361+
}
1362+
13281363
/// Returns a value uniquely identifying the enum variant in `v`.
13291364
///
13301365
/// If `T` is not an enum, calling this function will not result in undefined behavior, but the

0 commit comments

Comments
 (0)