Skip to content

Commit de0180e

Browse files
author
bors-servo
authored
Auto merge of #1003 - pepyakin:derive-ord-when-possible, r=fitzgen
Derive ord when possible Fixes #884 r? @fitzgen
2 parents 1906a26 + 27dad0b commit de0180e

17 files changed

+100
-35
lines changed

src/codegen/mod.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use ir::comp::{Base, Bitfield, BitfieldUnit, CompInfo, CompKind, Field,
1212
FieldData, FieldMethods, Method, MethodKind};
1313
use ir::context::{BindgenContext, ItemId};
1414
use ir::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault,
15-
CanDeriveHash, CanDerivePartialOrd, CanDerivePartialEq,
16-
CanDeriveEq};
15+
CanDeriveHash, CanDerivePartialOrd, CanDeriveOrd,
16+
CanDerivePartialEq, CanDeriveEq};
1717
use ir::dot;
1818
use ir::enum_ty::{Enum, EnumVariant, EnumVariantValue};
1919
use ir::function::{Abi, Function, FunctionSig};
@@ -1494,6 +1494,10 @@ impl CodeGenerator for CompInfo {
14941494
derives.push("PartialOrd");
14951495
}
14961496

1497+
if item.can_derive_ord(ctx) {
1498+
derives.push("Ord");
1499+
}
1500+
14971501
if item.can_derive_partialeq(ctx) {
14981502
derives.push("PartialEq");
14991503
}

src/ir/context.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use super::analysis::{CannotDeriveCopy, CannotDeriveDebug,
66
HasVtableAnalysis, HasDestructorAnalysis, UsedTemplateParameters,
77
HasFloat, analyze};
88
use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault,
9-
CanDeriveHash, CanDerivePartialOrd, CanDerivePartialEq,
10-
CanDeriveEq};
9+
CanDeriveHash, CanDerivePartialOrd, CanDeriveOrd,
10+
CanDerivePartialEq, CanDeriveEq};
1111
use super::int::IntKind;
1212
use super::item::{HasTypeParamInArray, IsOpaque, Item, ItemAncestors,
1313
ItemCanonicalPath, ItemSet};
@@ -91,6 +91,14 @@ impl CanDeriveEq for ItemId {
9191
}
9292
}
9393

94+
impl CanDeriveOrd for ItemId {
95+
fn can_derive_ord(&self, ctx: &BindgenContext) -> bool {
96+
ctx.options().derive_ord &&
97+
ctx.lookup_item_id_can_derive_partialeq_or_partialord(*self) &&
98+
!ctx.lookup_item_id_has_float(&self)
99+
}
100+
}
101+
94102
/// A key used to index a resolved type, so we only process it once.
95103
///
96104
/// This is almost always a USR string (an unique identifier generated by
@@ -2191,7 +2199,7 @@ impl BindgenContext {
21912199
fn compute_has_float(&mut self) {
21922200
let _t = self.timer("compute_has_float");
21932201
assert!(self.has_float.is_none());
2194-
if self.options.derive_eq {
2202+
if self.options.derive_eq || self.options.derive_ord {
21952203
self.has_float = Some(analyze::<HasFloat>(self));
21962204
}
21972205
}

src/ir/derive.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ pub trait CanDerivePartialEq {
9797
///
9898
/// This should ideally be a no-op that just returns `true`, but instead needs
9999
/// to be a recursive method that checks whether all the proper members can
100-
/// derive default or not, because of the limit rust has on 32 items as max in the
100+
/// derive partial ord or not, because of the limit rust has on 32 items as max in the
101101
/// array.
102102
pub trait CanDerivePartialOrd {
103103
/// Return `true` if `PartialOrd` can be derived for this thing, `false`
@@ -121,6 +121,19 @@ pub trait CanDeriveEq {
121121
-> bool;
122122
}
123123

124+
/// A trait that encapsulates the logic for whether or not we can derive `Ord`
125+
/// for a given thing.
126+
///
127+
/// This should ideally be a no-op that just returns `true`, but instead needs
128+
/// to be a recursive method that checks whether all the proper members can
129+
/// derive ord or not, because of the limit rust has on 32 items as max in the
130+
/// array.
131+
pub trait CanDeriveOrd {
132+
/// Return `true` if `Ord` can be derived for this thing, `false`
133+
/// otherwise.
134+
fn can_derive_ord(&self, ctx: &BindgenContext) -> bool;
135+
}
136+
124137
/// A trait that encapsulates the logic for whether or not we can derive `Hash`.
125138
/// The difference between this trait and the CanDeriveHash is that the type
126139
/// implementing this trait cannot use recursion or lookup result from fix point

src/ir/item.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use super::comment;
66
use super::comp::MethodKind;
77
use super::context::{BindgenContext, ItemId, PartialType};
88
use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault,
9-
CanDeriveHash, CanDerivePartialOrd, CanDerivePartialEq,
10-
CanDeriveEq};
9+
CanDeriveHash, CanDerivePartialOrd, CanDeriveOrd,
10+
CanDerivePartialEq, CanDeriveEq};
1111
use super::dot::DotAttributes;
1212
use super::function::{Function, FunctionKind};
1313
use super::item_kind::ItemKind;
@@ -353,6 +353,14 @@ impl CanDeriveEq for Item {
353353
}
354354
}
355355

356+
impl CanDeriveOrd for Item {
357+
fn can_derive_ord(&self, ctx: &BindgenContext) -> bool {
358+
ctx.options().derive_ord &&
359+
ctx.lookup_item_id_can_derive_partialeq_or_partialord(self.id()) &&
360+
!ctx.lookup_item_id_has_float(&self.id())
361+
}
362+
}
363+
356364
/// An item is the base of the bindgen representation, it can be either a
357365
/// module, a type, a function, or a variable (see `ItemKind` for more
358366
/// information).

src/lib.rs

+23
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,10 @@ impl Builder {
265265
output_vector.push("--with-derive-partialord".into());
266266
}
267267

268+
if self.options.derive_ord {
269+
output_vector.push("--with-derive-ord".into());
270+
}
271+
268272
if self.options.derive_partialeq {
269273
output_vector.push("--with-derive-partialeq".into());
270274
}
@@ -819,7 +823,21 @@ impl Builder {
819823
}
820824

821825
/// Set whether `PartialOrd` should be derived by default.
826+
/// If we don't compute partialord, we also cannot compute
827+
/// ord. Set the derive_ord to `false` when doit is `false`.
822828
pub fn derive_partialord(mut self, doit: bool) -> Self {
829+
self.options.derive_partialord = doit;
830+
if !doit {
831+
self.options.derive_ord = false;
832+
}
833+
self
834+
}
835+
836+
/// Set whether `Ord` should be derived by default.
837+
/// We can't compute `Ord` without computing `PartialOrd`,
838+
/// so we set the same option to derive_partialord.
839+
pub fn derive_ord(mut self, doit: bool) -> Self {
840+
self.options.derive_ord = doit;
823841
self.options.derive_partialord = doit;
824842
self
825843
}
@@ -1190,6 +1208,10 @@ struct BindgenOptions {
11901208
/// and types.
11911209
derive_partialord: bool,
11921210

1211+
/// True if we should derive Ord trait implementations for C/C++ structures
1212+
/// and types.
1213+
derive_ord: bool,
1214+
11931215
/// True if we should derive PartialEq trait implementations for C/C++ structures
11941216
/// and types.
11951217
derive_partialeq: bool,
@@ -1340,6 +1362,7 @@ impl Default for BindgenOptions {
13401362
derive_default: false,
13411363
derive_hash: false,
13421364
derive_partialord: false,
1365+
derive_ord: false,
13431366
derive_partialeq: false,
13441367
derive_eq: false,
13451368
enable_cxx_namespaces: false,

src/options.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,12 @@ where
8888
.help("Derive partialord on any type."),
8989
Arg::with_name("with-derive-eq")
9090
.long("with-derive-eq")
91-
.help("Derive eq on any type. Enable this option also enables --with-derive-partialeq"),
91+
.help("Derive eq on any type. Enable this option also \
92+
enables --with-derive-partialeq"),
93+
Arg::with_name("with-derive-ord")
94+
.long("with-derive-ord")
95+
.help("Derive ord on any type. Enable this option also \
96+
enables --with-derive-partialord"),
9297
Arg::with_name("no-doc-comments")
9398
.long("no-doc-comments")
9499
.help("Avoid including doc comments in the output, see: \
@@ -351,6 +356,10 @@ where
351356
builder = builder.derive_eq(true);
352357
}
353358

359+
if matches.is_present("with-derive-ord") {
360+
builder = builder.derive_ord(true);
361+
}
362+
354363
if matches.is_present("no-derive-default") {
355364
builder = builder.derive_default(false);
356365
}

tests/expectations/tests/derive-hash-struct-with-anon-struct-float.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66

77

8-
/// A struct containing a struct containing a float that cannot derive hash/eq but can derive partialeq and partialord
8+
/// A struct containing a struct containing a float that cannot derive Hash/Eq/Ord but can derive PartialEq/PartialOrd
99
#[repr(C)]
1010
#[derive(Debug, Default, Copy, PartialOrd, PartialEq)]
1111
pub struct foo {

tests/expectations/tests/derive-hash-struct-with-float-array.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66

77

8-
/// A struct containing an array of floats that cannot derive hash/eq but can derive partialeq and partialord
8+
/// A struct containing an array of floats that cannot derive Hash/Eq/Ord but can derive PartialEq/PartialOrd
99
#[repr(C)]
1010
#[derive(Debug, Default, Copy, PartialOrd, PartialEq)]
1111
pub struct foo {

tests/expectations/tests/derive-hash-struct-with-pointer.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66

77

8-
/// Pointers can derive Hash/PartialOrd/PartialEq/Eq
8+
/// Pointers can derive Hash/PartialOrd/Ord/PartialEq/Eq
99
#[repr(C)]
10-
#[derive(Debug, Copy, Hash, PartialOrd, PartialEq, Eq)]
10+
#[derive(Debug, Copy, Hash, PartialOrd, Ord, PartialEq, Eq)]
1111
pub struct ConstPtrMutObj {
1212
pub bar: *const ::std::os::raw::c_int,
1313
}
@@ -45,7 +45,7 @@ impl Default for ConstPtrMutObj {
4545
}
4646
}
4747
#[repr(C)]
48-
#[derive(Debug, Copy, Hash, PartialOrd, PartialEq, Eq)]
48+
#[derive(Debug, Copy, Hash, PartialOrd, Ord, PartialEq, Eq)]
4949
pub struct MutPtrMutObj {
5050
pub bar: *mut ::std::os::raw::c_int,
5151
}
@@ -83,7 +83,7 @@ impl Default for MutPtrMutObj {
8383
}
8484
}
8585
#[repr(C)]
86-
#[derive(Debug, Copy, Hash, PartialOrd, PartialEq, Eq)]
86+
#[derive(Debug, Copy, Hash, PartialOrd, Ord, PartialEq, Eq)]
8787
pub struct MutPtrConstObj {
8888
pub bar: *const ::std::os::raw::c_int,
8989
}
@@ -121,7 +121,7 @@ impl Default for MutPtrConstObj {
121121
}
122122
}
123123
#[repr(C)]
124-
#[derive(Debug, Copy, Hash, PartialOrd, PartialEq, Eq)]
124+
#[derive(Debug, Copy, Hash, PartialOrd, Ord, PartialEq, Eq)]
125125
pub struct ConstPtrConstObj {
126126
pub bar: *const ::std::os::raw::c_int,
127127
}

tests/expectations/tests/derive-hash-template-def-float.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66

77

8-
/// Template definition containing a float, which cannot derive hash/eq but can derive partialeq and partialord.
8+
/// Template definition containing a float, which cannot derive Hash/Eq/Ord but can derive PartialEq/PartialOrd.
99
#[repr(C)]
1010
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq)]
1111
pub struct foo<T> {

tests/expectations/tests/derive-hash-template-inst-float.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66

77

8-
/// Template definition that doesn't contain float can derive hash/partialord/partialeq/eq
8+
/// Template definition that doesn't contain float can derive Hash/PartialOrd/Ord/PartialEq/Eq
99
#[repr(C)]
10-
#[derive(Debug, Copy, Clone, Hash, PartialOrd, PartialEq, Eq)]
10+
#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
1111
pub struct foo<T> {
1212
pub data: T,
1313
pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
@@ -17,9 +17,9 @@ impl<T> Default for foo<T> {
1717
unsafe { ::std::mem::zeroed() }
1818
}
1919
}
20-
/// Can derive hash/partialeq/eq when instantiated with int
20+
/// Can derive Hash/PartialOrd/Ord/PartialEq/Eq when instantiated with int
2121
#[repr(C)]
22-
#[derive(Debug, Copy, Hash, PartialOrd, PartialEq, Eq)]
22+
#[derive(Debug, Copy, Hash, PartialOrd, Ord, PartialEq, Eq)]
2323
pub struct IntStr {
2424
pub a: foo<::std::os::raw::c_int>,
2525
}
@@ -56,7 +56,7 @@ impl Default for IntStr {
5656
unsafe { ::std::mem::zeroed() }
5757
}
5858
}
59-
/// Cannot derive hash/eq when instantiated with float but can derive partialeq
59+
/// Cannot derive Hash/Eq/Ord when instantiated with float but can derive PartialEq/PartialOrd
6060
#[repr(C)]
6161
#[derive(Debug, Copy, PartialOrd, PartialEq)]
6262
pub struct FloatStr {

tests/headers/derive-hash-blacklisting.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-partialeq --with-derive-eq --whitelist-type 'Whitelisted.*' --blacklist-type Blacklisted --raw-line "#[repr(C)] #[derive(Debug, Hash, Copy, Clone, PartialEq, Eq)] pub struct Blacklisted<T> {t: T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>> }"
1+
// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-ord --with-derive-partialeq --with-derive-eq --whitelist-type 'Whitelisted.*' --blacklist-type Blacklisted --raw-line "#[repr(C)] #[derive(Debug, Hash, Copy, Clone, PartialEq, Eq)] pub struct Blacklisted<T> {t: T, pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>> }"
22
//
33
template <class T>
44
struct Blacklisted {

tests/headers/derive-hash-struct-with-anon-struct-float.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-partialeq --with-derive-eq
1+
// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-ord --with-derive-partialeq --with-derive-eq
22
//
3-
/// A struct containing a struct containing a float that cannot derive hash/eq but can derive partialeq and partialord
3+
/// A struct containing a struct containing a float that cannot derive Hash/Eq/Ord but can derive PartialEq/PartialOrd
44
struct foo {
55
struct {
66
float a;
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-partialeq --with-derive-eq
1+
// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-ord --with-derive-partialeq --with-derive-eq
22
//
3-
/// A struct containing an array of floats that cannot derive hash/eq but can derive partialeq and partialord
3+
/// A struct containing an array of floats that cannot derive Hash/Eq/Ord but can derive PartialEq/PartialOrd
44
struct foo {
55
float bar[3];
66
};

tests/headers/derive-hash-struct-with-pointer.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-partialeq --with-derive-eq
1+
// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-ord --with-derive-partialeq --with-derive-eq
22
//
3-
/// Pointers can derive Hash/PartialOrd/PartialEq/Eq
3+
/// Pointers can derive Hash/PartialOrd/Ord/PartialEq/Eq
44
struct ConstPtrMutObj {
55
int* const bar;
66
};

tests/headers/derive-hash-template-def-float.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-partialeq --with-derive-eq
1+
// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-ord --with-derive-partialeq --with-derive-eq
22
//
3-
/// Template definition containing a float, which cannot derive hash/eq but can derive partialeq and partialord.
3+
/// Template definition containing a float, which cannot derive Hash/Eq/Ord but can derive PartialEq/PartialOrd.
44
template <typename T>
55
struct foo {
66
T data;
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-partialeq --with-derive-eq
1+
// bindgen-flags: --with-derive-hash --with-derive-partialord --with-derive-ord --with-derive-partialeq --with-derive-eq
22
//
3-
/// Template definition that doesn't contain float can derive hash/partialord/partialeq/eq
3+
/// Template definition that doesn't contain float can derive Hash/PartialOrd/Ord/PartialEq/Eq
44
template <typename T>
55
struct foo {
66
T data;
77
};
88

9-
/// Can derive hash/partialeq/eq when instantiated with int
9+
/// Can derive Hash/PartialOrd/Ord/PartialEq/Eq when instantiated with int
1010
struct IntStr {
1111
foo<int> a;
1212
};
1313

14-
/// Cannot derive hash/eq when instantiated with float but can derive partialeq
14+
/// Cannot derive Hash/Eq/Ord when instantiated with float but can derive PartialEq/PartialOrd
1515
struct FloatStr {
1616
foo<float> a;
1717
};

0 commit comments

Comments
 (0)