Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement Ord for OutlivesPredicate and other types #50930

Merged
merged 1 commit into from
May 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -930,7 +930,7 @@ pub enum PatKind {
Slice(HirVec<P<Pat>>, Option<P<Pat>>, HirVec<P<Pat>>),
}

#[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,
Expand Down Expand Up @@ -1523,7 +1523,7 @@ pub struct Destination {
pub target_id: Result<NodeId, LoopIdError>,
}

#[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,
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/const_val.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>),
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/mir/interpret/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ pub trait PointerArithmetic: layout::HasDataLayout {
impl<T: layout::HasDataLayout> 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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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<Size, AllocId>);

impl Relocations {
Expand Down Expand Up @@ -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<Block>,
len: Size,
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/mir/interpret/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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),
Expand All @@ -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,
}
Expand Down Expand Up @@ -194,7 +194,7 @@ impl ::std::convert::From<MemoryPointer> 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),
Expand Down
46 changes: 44 additions & 2 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<Ordering> {
Some(self.sty.cmp(&other.sty))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be Some(self.cmp(other)), to keep the implementation details in the Ord impl.

}
}

impl<'tcx> PartialEq for TyS<'tcx> {
#[inline]
fn eq(&self, other: &TyS<'tcx>) -> bool {
Expand Down Expand Up @@ -578,6 +590,22 @@ impl <'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for Ty<'tcx> {
#[derive(Debug, RustcEncodable)]
pub struct Slice<T>([T]);

impl<T> Ord for Slice<T> where T: Ord {
fn cmp(&self, other: &Slice<T>) -> Ordering {
if self == other { Ordering::Equal } else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice optimization!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

credit goes to @nikomatsakis

<[T] as Ord>::cmp(&self.0, &other.0)
}
}
}

impl<T> PartialOrd for Slice<T> where T: PartialOrd {
fn partial_cmp(&self, other: &Slice<T>) -> Option<Ordering> {
if self == other { Some(Ordering::Equal) } else {
<[T] as PartialOrd>::partial_cmp(&self.0, &other.0)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here (Some(self.cmp(other))).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some(self.cmp(other)) will require the bound T: Ord, which I was not sure we wanted to impose for all types that that maybe only want to implement PartialOrd?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I somehow missed that this was generic - seems fine, then.

}
}

impl<T> PartialEq for Slice<T> {
#[inline]
fn eq(&self, other: &Slice<T>) -> bool {
Expand Down Expand Up @@ -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<A,B>(pub A, pub B); // `A : B`
pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<ty::Region<'tcx>,
Expand Down Expand Up @@ -1606,6 +1634,20 @@ pub struct AdtDef {
pub repr: ReprOptions,
}

impl PartialOrd for AdtDef {
fn partial_cmp(&self, other: &AdtDef) -> Option<Ordering> {
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]
Expand Down
32 changes: 16 additions & 16 deletions src/librustc/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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>,
}
Expand Down Expand Up @@ -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>),
Expand Down Expand Up @@ -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>,
Expand Down Expand Up @@ -728,7 +728,7 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> {
/// erase, or otherwise "discharge" these bound regions, we change the
/// type from `Binder<T>` 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>(T);

impl<T> Binder<T> {
Expand Down Expand Up @@ -834,7 +834,7 @@ impl<T> Binder<T> {

/// Represents the projection of an associated type. In explicit UFCS
/// form this would be written `<T as Trait<..>>::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>,
Expand Down Expand Up @@ -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<Ty<'tcx>>,
pub variadic: bool,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
}
Expand All @@ -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),
Expand All @@ -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>,
Expand Down Expand Up @@ -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>,

Expand Down
23 changes: 23 additions & 0 deletions src/librustc/ty/subst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to implement all of this manually, just add #[derive(PartialEq, Eq, PartialOrd, Ord)] on UnpackedKind and implement this method going through that. That's how other traits are implemented on Kind.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be unresolved?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops missed this one. Here is a pr for that #54074


(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<Ordering> {
Some(self.cmp(&other))
}
}

impl<'tcx> From<ty::Region<'tcx>> for Kind<'tcx> {
fn from(r: ty::Region<'tcx>) -> Kind<'tcx> {
UnpackedKind::Lifetime(r).pack()
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_data_structures/sorted_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<K: Ord, V> {
data: Vec<(K,V)>
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_target/abi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ impl AddAssign for Size {
/// Each field is a power of two, giving the alignment a maximum value
/// of 2<sup>(2<sup>8</sup> - 1)</sup>, which is limited by LLVM to a
/// maximum capacity of 2<sup>29</sup> or 536870912.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash, Debug, RustcEncodable, RustcDecodable)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a mistake, because this type does not have a defined ordering (see the min/max methods).

I'll try to figure out if I can fix it locally (as part of a PR that would probably remove the need for using this type in most places, by replacing it with one alignment, instead of two).

pub struct Align {
abi_pow2: u8,
pref_pow2: u8,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_target/spec/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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().)
Expand Down
Loading