diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index caae79961a6d..2b0e17bfb5cd 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -930,7 +930,7 @@ pub enum PatKind {
Slice(HirVec
>, Option
>, HirVec
>),
}
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum Mutability {
MutMutable,
MutImmutable,
@@ -1523,7 +1523,7 @@ pub struct Destination {
pub target_id: Result,
}
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum GeneratorMovability {
Static,
Movable,
@@ -1775,7 +1775,7 @@ pub enum IsAuto {
No
}
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq,PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum Unsafety {
Unsafe,
Normal,
diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs
index 3a76f75d0183..d7f116705113 100644
--- a/src/librustc/middle/const_val.rs
+++ b/src/librustc/middle/const_val.rs
@@ -22,7 +22,7 @@ use rustc_data_structures::sync::Lrc;
pub type EvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ConstEvalErr<'tcx>>;
-#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq)]
+#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq, Ord, PartialOrd)]
pub enum ConstVal<'tcx> {
Unevaluated(DefId, &'tcx Substs<'tcx>),
Value(ConstValue<'tcx>),
diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs
index 9827ee51ba29..48954b1f0aa7 100644
--- a/src/librustc/mir/interpret/mod.rs
+++ b/src/librustc/mir/interpret/mod.rs
@@ -109,7 +109,7 @@ pub trait PointerArithmetic: layout::HasDataLayout {
impl PointerArithmetic for T {}
-#[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
pub struct MemoryPointer {
pub alloc_id: AllocId,
pub offset: Size,
@@ -335,7 +335,7 @@ impl<'tcx, M: fmt::Debug + Eq + Hash + Clone> AllocMap<'tcx, M> {
}
}
-#[derive(Clone, Debug, Eq, PartialEq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub struct Allocation {
/// The actual bytes of the allocation.
/// Note that the bytes of a pointer represent the offset of the pointer
@@ -384,7 +384,7 @@ impl Allocation {
impl<'tcx> ::serialize::UseSpecializedDecodable for &'tcx Allocation {}
-#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct Relocations(SortedMap);
impl Relocations {
@@ -455,7 +455,7 @@ pub fn read_target_uint(endianness: layout::Endian, mut source: &[u8]) -> Result
type Block = u64;
const BLOCK_SIZE: u64 = 64;
-#[derive(Clone, Debug, Eq, PartialEq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub struct UndefMask {
blocks: Vec,
len: Size,
diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs
index 5ac2f7f356ea..7ad6826b2f67 100644
--- a/src/librustc/mir/interpret/value.rs
+++ b/src/librustc/mir/interpret/value.rs
@@ -7,7 +7,7 @@ use super::{EvalResult, MemoryPointer, PointerArithmetic, Allocation};
/// Represents a constant value in Rust. ByVal and ByValPair are optimizations which
/// matches Value's optimizations for easy conversions between these two types
-#[derive(Clone, Copy, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash)]
+#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)]
pub enum ConstValue<'tcx> {
/// Used only for types with layout::abi::Scalar ABI and ZSTs which use PrimVal::Undef
ByVal(PrimVal),
@@ -76,7 +76,7 @@ impl<'tcx> ConstValue<'tcx> {
/// For optimization of a few very common cases, there is also a representation for a pair of
/// primitive values (`ByValPair`). It allows Miri to avoid making allocations for checked binary
/// operations and fat pointers. This idea was taken from rustc's codegen.
-#[derive(Clone, Copy, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash)]
+#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
pub enum Value {
ByRef(Pointer, Align),
ByVal(PrimVal),
@@ -99,7 +99,7 @@ impl<'tcx> ty::TypeFoldable<'tcx> for Value {
/// I (@oli-obk) believe it is less easy to mix up generic primvals and primvals that are just
/// the representation of pointers. Also all the sites that convert between primvals and pointers
/// are explicit now (and rare!)
-#[derive(Clone, Copy, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash)]
+#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
pub struct Pointer {
pub primval: PrimVal,
}
@@ -194,7 +194,7 @@ impl ::std::convert::From for Pointer {
/// `memory::Allocation`. It is in many ways like a small chunk of a `Allocation`, up to 8 bytes in
/// size. Like a range of bytes in an `Allocation`, a `PrimVal` can either represent the raw bytes
/// of a simple value, a pointer into another `Allocation`, or be undefined.
-#[derive(Clone, Copy, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash)]
+#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
pub enum PrimVal {
/// The raw bytes of a simple value.
Bytes(u128),
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index b975f9e51958..4507da1c698e 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -39,7 +39,7 @@ use util::nodemap::{NodeSet, DefIdMap, FxHashMap};
use serialize::{self, Encodable, Encoder};
use std::cell::RefCell;
-use std::cmp;
+use std::cmp::{self, Ordering};
use std::fmt;
use std::hash::{Hash, Hasher};
use std::ops::Deref;
@@ -491,6 +491,18 @@ pub struct TyS<'tcx> {
region_depth: u32,
}
+impl<'tcx> Ord for TyS<'tcx> {
+ fn cmp(&self, other: &TyS<'tcx>) -> Ordering {
+ self.sty.cmp(&other.sty)
+ }
+}
+
+impl<'tcx> PartialOrd for TyS<'tcx> {
+ fn partial_cmp(&self, other: &TyS<'tcx>) -> Option {
+ Some(self.sty.cmp(&other.sty))
+ }
+}
+
impl<'tcx> PartialEq for TyS<'tcx> {
#[inline]
fn eq(&self, other: &TyS<'tcx>) -> bool {
@@ -578,6 +590,22 @@ impl <'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for Ty<'tcx> {
#[derive(Debug, RustcEncodable)]
pub struct Slice([T]);
+impl Ord for Slice where T: Ord {
+ fn cmp(&self, other: &Slice) -> Ordering {
+ if self == other { Ordering::Equal } else {
+ <[T] as Ord>::cmp(&self.0, &other.0)
+ }
+ }
+}
+
+impl PartialOrd for Slice where T: PartialOrd {
+ fn partial_cmp(&self, other: &Slice) -> Option {
+ if self == other { Some(Ordering::Equal) } else {
+ <[T] as PartialOrd>::partial_cmp(&self.0, &other.0)
+ }
+ }
+}
+
impl PartialEq for Slice {
#[inline]
fn eq(&self, other: &Slice) -> bool {
@@ -1104,7 +1132,7 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
}
}
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct OutlivesPredicate(pub A, pub B); // `A : B`
pub type PolyOutlivesPredicate = ty::Binder>;
pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate,
@@ -1606,6 +1634,20 @@ pub struct AdtDef {
pub repr: ReprOptions,
}
+impl PartialOrd for AdtDef {
+ fn partial_cmp(&self, other: &AdtDef) -> Option {
+ Some(self.cmp(&other))
+ }
+}
+
+/// There should be only one AdtDef for each `did`, therefore
+/// it is fine to implement `Ord` only based on `did`.
+impl Ord for AdtDef {
+ fn cmp(&self, other: &AdtDef) -> Ordering {
+ self.did.cmp(&other.did)
+ }
+}
+
impl PartialEq for AdtDef {
// AdtDef are always interned and this is part of TyS equality
#[inline]
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index d9797bf4985b..faf93ab30b70 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -34,7 +34,7 @@ use hir;
use self::InferTy::*;
use self::TypeVariants::*;
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct TypeAndMut<'tcx> {
pub ty: Ty<'tcx>,
pub mutbl: hir::Mutability,
@@ -80,7 +80,7 @@ impl BoundRegion {
/// NB: If you change this, you'll probably want to change the corresponding
/// AST structure in libsyntax/ast.rs as well.
-#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
pub enum TypeVariants<'tcx> {
/// The primitive boolean type. Written as `bool`.
TyBool,
@@ -268,7 +268,7 @@ pub enum TypeVariants<'tcx> {
///
/// It'd be nice to split this struct into ClosureSubsts and
/// GeneratorSubsts, I believe. -nmatsakis
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct ClosureSubsts<'tcx> {
/// Lifetime and type parameters from the enclosing function,
/// concatenated with the types of the upvars.
@@ -351,7 +351,7 @@ impl<'tcx> ClosureSubsts<'tcx> {
}
}
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct GeneratorSubsts<'tcx> {
pub substs: &'tcx Substs<'tcx>,
}
@@ -484,7 +484,7 @@ impl<'tcx> UpvarSubsts<'tcx> {
}
}
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum ExistentialPredicate<'tcx> {
/// e.g. Iterator
Trait(ExistentialTraitRef<'tcx>),
@@ -660,7 +660,7 @@ impl<'tcx> PolyTraitRef<'tcx> {
///
/// The substitutions don't include the erased `Self`, only trait
/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above).
-#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub struct ExistentialTraitRef<'tcx> {
pub def_id: DefId,
pub substs: &'tcx Substs<'tcx>,
@@ -728,7 +728,7 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> {
/// erase, or otherwise "discharge" these bound regions, we change the
/// type from `Binder` to just `T` (see
/// e.g. `liberate_late_bound_regions`).
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct Binder(T);
impl Binder {
@@ -834,7 +834,7 @@ impl Binder {
/// Represents the projection of an associated type. In explicit UFCS
/// form this would be written `>::N`.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct ProjectionTy<'tcx> {
/// The parameters of the associated item.
pub substs: &'tcx Substs<'tcx>,
@@ -902,7 +902,7 @@ impl<'tcx> PolyGenSig<'tcx> {
/// - `inputs` is the list of arguments and their modes.
/// - `output` is the return type.
/// - `variadic` indicates whether this is a variadic function. (only true for foreign fns)
-#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub struct FnSig<'tcx> {
pub inputs_and_output: &'tcx Slice>,
pub variadic: bool,
@@ -946,7 +946,7 @@ impl<'tcx> PolyFnSig<'tcx> {
}
}
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub struct ParamTy {
pub idx: u32,
pub name: InternedString,
@@ -1148,17 +1148,17 @@ pub struct EarlyBoundRegion {
pub name: InternedString,
}
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub struct TyVid {
pub index: u32,
}
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub struct IntVid {
pub index: u32,
}
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub struct FloatVid {
pub index: u32,
}
@@ -1169,7 +1169,7 @@ newtype_index!(RegionVid
DEBUG_FORMAT = custom,
});
-#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub enum InferTy {
TyVar(TyVid),
IntVar(IntVid),
@@ -1189,7 +1189,7 @@ pub enum InferTy {
newtype_index!(CanonicalVar);
/// A `ProjectionPredicate` for an `ExistentialTraitRef`.
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct ExistentialProjection<'tcx> {
pub item_def_id: DefId,
pub substs: &'tcx Substs<'tcx>,
@@ -1758,7 +1758,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
}
/// Typed constant value.
-#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq)]
+#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq, Ord, PartialOrd)]
pub struct Const<'tcx> {
pub ty: Ty<'tcx>,
diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs
index f44e1533f520..2e3c6df9754d 100644
--- a/src/librustc/ty/subst.rs
+++ b/src/librustc/ty/subst.rs
@@ -20,6 +20,7 @@ use rustc_data_structures::accumulate_vec::AccumulateVec;
use rustc_data_structures::array_vec::ArrayVec;
use core::intrinsics;
+use std::cmp::Ordering;
use std::fmt;
use std::marker::PhantomData;
use std::mem;
@@ -70,6 +71,28 @@ impl<'tcx> UnpackedKind<'tcx> {
}
}
+impl<'tcx> Ord for Kind<'tcx> {
+ fn cmp(&self, other: &Kind) -> Ordering {
+ match (self.unpack(), other.unpack()) {
+ (UnpackedKind::Type(_), UnpackedKind::Lifetime(_)) => Ordering::Greater,
+
+ (UnpackedKind::Type(ty1), UnpackedKind::Type(ty2)) => {
+ ty1.sty.cmp(&ty2.sty)
+ }
+
+ (UnpackedKind::Lifetime(reg1), UnpackedKind::Lifetime(reg2)) => reg1.cmp(reg2),
+
+ (UnpackedKind::Lifetime(_), UnpackedKind::Type(_)) => Ordering::Less,
+ }
+ }
+}
+
+impl<'tcx> PartialOrd for Kind<'tcx> {
+ fn partial_cmp(&self, other: &Kind) -> Option {
+ Some(self.cmp(&other))
+ }
+}
+
impl<'tcx> From> for Kind<'tcx> {
fn from(r: ty::Region<'tcx>) -> Kind<'tcx> {
UnpackedKind::Lifetime(r).pack()
diff --git a/src/librustc_data_structures/sorted_map.rs b/src/librustc_data_structures/sorted_map.rs
index e14bd33c82c1..9f1a795b3500 100644
--- a/src/librustc_data_structures/sorted_map.rs
+++ b/src/librustc_data_structures/sorted_map.rs
@@ -22,7 +22,8 @@ use std::ops::{RangeBounds, Bound, Index, IndexMut};
/// stores data in a more compact way. It also supports accessing contiguous
/// ranges of elements as a slice, and slices of already sorted elements can be
/// inserted efficiently.
-#[derive(Clone, PartialEq, Eq, Hash, Default, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Debug, RustcEncodable,
+ RustcDecodable)]
pub struct SortedMap {
data: Vec<(K,V)>
}
diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs
index 7f593aff21d2..4b11de097738 100644
--- a/src/librustc_target/abi/mod.rs
+++ b/src/librustc_target/abi/mod.rs
@@ -332,7 +332,7 @@ impl AddAssign for Size {
/// Each field is a power of two, giving the alignment a maximum value
/// of 2(28 - 1), which is limited by LLVM to a
/// maximum capacity of 229 or 536870912.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct Align {
abi_pow2: u8,
pref_pow2: u8,
diff --git a/src/librustc_target/spec/abi.rs b/src/librustc_target/spec/abi.rs
index ed2eb2099069..927d224389ff 100644
--- a/src/librustc_target/spec/abi.rs
+++ b/src/librustc_target/spec/abi.rs
@@ -10,7 +10,7 @@
use std::fmt;
-#[derive(PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Clone, Copy, Debug)]
+#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Clone, Copy, Debug)]
pub enum Abi {
// NB: This ordering MUST match the AbiDatas array below.
// (This is ensured by the test indices_are_correct().)
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 72d5323a8722..e1e220f49c97 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -667,7 +667,7 @@ pub enum PatKind {
Mac(Mac),
}
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum Mutability {
Mutable,
Immutable,