Skip to content

Commit 1906a26

Browse files
author
bors-servo
authored
Auto merge of rust-lang#1002 - pepyakin:derive-partialord-when-possible, r=fitzgen
Derive PartialOrd when possible Fixes rust-lang#882 r? @fitzgen
2 parents da942c4 + e4a4b47 commit 1906a26

21 files changed

+205
-131
lines changed

src/codegen/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +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, CanDerivePartialEq, CanDeriveEq};
15+
CanDeriveHash, CanDerivePartialOrd, CanDerivePartialEq,
16+
CanDeriveEq};
1617
use ir::dot;
1718
use ir::enum_ty::{Enum, EnumVariant, EnumVariantValue};
1819
use ir::function::{Abi, Function, FunctionSig};
@@ -1489,6 +1490,10 @@ impl CodeGenerator for CompInfo {
14891490
derives.push("Hash");
14901491
}
14911492

1493+
if item.can_derive_partialord(ctx) {
1494+
derives.push("PartialOrd");
1495+
}
1496+
14921497
if item.can_derive_partialeq(ctx) {
14931498
derives.push("PartialEq");
14941499
}

src/ir/analysis/derive_partial_eq.rs renamed to src/ir/analysis/derive_partial_eq_or_partial_ord.rs

Lines changed: 64 additions & 64 deletions
Large diffs are not rendered by default.

src/ir/analysis/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ mod has_type_param_in_array;
5555
pub use self::has_type_param_in_array::HasTypeParameterInArray;
5656
mod derive_hash;
5757
pub use self::derive_hash::CannotDeriveHash;
58-
mod derive_partial_eq;
59-
pub use self::derive_partial_eq::CannotDerivePartialEq;
58+
mod derive_partial_eq_or_partial_ord;
59+
pub use self::derive_partial_eq_or_partial_ord::CannotDerivePartialEqOrPartialOrd;
6060
mod has_float;
6161
pub use self::has_float::HasFloat;
6262

src/ir/context.rs

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
33
use super::analysis::{CannotDeriveCopy, CannotDeriveDebug,
44
CannotDeriveDefault, CannotDeriveHash,
5-
CannotDerivePartialEq, HasTypeParameterInArray,
5+
CannotDerivePartialEqOrPartialOrd, HasTypeParameterInArray,
66
HasVtableAnalysis, HasDestructorAnalysis, UsedTemplateParameters,
77
HasFloat, analyze};
88
use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault,
9-
CanDeriveHash, CanDerivePartialEq, CanDeriveEq};
9+
CanDeriveHash, CanDerivePartialOrd, CanDerivePartialEq,
10+
CanDeriveEq};
1011
use super::int::IntKind;
1112
use super::item::{HasTypeParamInArray, IsOpaque, Item, ItemAncestors,
1213
ItemCanonicalPath, ItemSet};
@@ -68,17 +69,24 @@ impl CanDeriveHash for ItemId {
6869
}
6970
}
7071

72+
impl CanDerivePartialOrd for ItemId {
73+
fn can_derive_partialord(&self, ctx: &BindgenContext) -> bool {
74+
ctx.options().derive_partialord &&
75+
ctx.lookup_item_id_can_derive_partialeq_or_partialord(*self)
76+
}
77+
}
78+
7179
impl CanDerivePartialEq for ItemId {
7280
fn can_derive_partialeq(&self, ctx: &BindgenContext) -> bool {
7381
ctx.options().derive_partialeq &&
74-
ctx.lookup_item_id_can_derive_partialeq(*self)
82+
ctx.lookup_item_id_can_derive_partialeq_or_partialord(*self)
7583
}
7684
}
7785

7886
impl CanDeriveEq for ItemId {
7987
fn can_derive_eq(&self, ctx: &BindgenContext) -> bool {
8088
ctx.options().derive_eq &&
81-
ctx.lookup_item_id_can_derive_partialeq(*self) &&
89+
ctx.lookup_item_id_can_derive_partialeq_or_partialord(*self) &&
8290
!ctx.lookup_item_id_has_float(&self)
8391
}
8492
}
@@ -225,7 +233,7 @@ pub struct BindgenContext {
225233
///
226234
/// This is populated when we enter codegen by `compute_can_derive_partialeq`
227235
/// and is always `None` before that and `Some` after.
228-
cannot_derive_partialeq: Option<HashSet<ItemId>>,
236+
cannot_derive_partialeq_or_partialord: Option<HashSet<ItemId>>,
229237

230238
/// The set of (`ItemId's of`) types that has vtable.
231239
///
@@ -392,7 +400,7 @@ impl BindgenContext {
392400
cannot_derive_copy: None,
393401
cannot_derive_copy_in_array: None,
394402
cannot_derive_hash: None,
395-
cannot_derive_partialeq: None,
403+
cannot_derive_partialeq_or_partialord: None,
396404
have_vtable: None,
397405
have_destructor: None,
398406
has_type_param_in_array: None,
@@ -947,7 +955,7 @@ impl BindgenContext {
947955
self.compute_has_type_param_in_array();
948956
self.compute_has_float();
949957
self.compute_cannot_derive_hash();
950-
self.compute_cannot_derive_partialeq_or_eq();
958+
self.compute_cannot_derive_partialord_partialeq_or_eq();
951959

952960
let ret = cb(self);
953961
self.in_codegen = false;
@@ -2123,27 +2131,26 @@ impl BindgenContext {
21232131
!self.cannot_derive_hash.as_ref().unwrap().contains(&id)
21242132
}
21252133

2126-
/// Compute whether we can derive PartialEq. This method is also used in calculating
2127-
/// whether we can derive Eq
2128-
fn compute_cannot_derive_partialeq_or_eq(&mut self) {
2129-
let _t = self.timer("compute_cannot_derive_partialeq_or_eq");
2130-
assert!(self.cannot_derive_partialeq.is_none());
2131-
if self.options.derive_partialeq || self.options.derive_eq {
2132-
self.cannot_derive_partialeq = Some(analyze::<CannotDerivePartialEq>(self));
2134+
/// Compute whether we can derive PartialOrd, PartialEq or Eq.
2135+
fn compute_cannot_derive_partialord_partialeq_or_eq(&mut self) {
2136+
let _t = self.timer("compute_cannot_derive_partialord_partialeq_or_eq");
2137+
assert!(self.cannot_derive_partialeq_or_partialord.is_none());
2138+
if self.options.derive_partialord || self.options.derive_partialeq || self.options.derive_eq {
2139+
self.cannot_derive_partialeq_or_partialord = Some(analyze::<CannotDerivePartialEqOrPartialOrd>(self));
21332140
}
21342141
}
21352142

21362143
/// Look up whether the item with `id` can
2137-
/// derive partialeq or not.
2138-
pub fn lookup_item_id_can_derive_partialeq(&self, id: ItemId) -> bool {
2144+
/// derive partialeq or partialord.
2145+
pub fn lookup_item_id_can_derive_partialeq_or_partialord(&self, id: ItemId) -> bool {
21392146
assert!(
21402147
self.in_codegen_phase(),
2141-
"We only compute can_derive_debug when we enter codegen"
2148+
"We only compute can_derive_partialeq_or_partialord when we enter codegen"
21422149
);
21432150

21442151
// Look up the computed value for whether the item with `id` can
21452152
// derive partialeq or not.
2146-
!self.cannot_derive_partialeq.as_ref().unwrap().contains(&id)
2153+
!self.cannot_derive_partialeq_or_partialord.as_ref().unwrap().contains(&id)
21472154
}
21482155

21492156
/// Look up whether the item with `id` can

src/ir/derive.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,19 +79,32 @@ pub trait CanDeriveHash {
7979
fn can_derive_hash(&self, ctx: &BindgenContext) -> bool;
8080
}
8181

82-
/// A trait that encapsulates the logic for whether or not we can derive `PartialEq`
82+
/// A trait that encapsulates the logic for whether or not we can derive `PartialEq`
8383
/// for a given thing.
8484
///
8585
/// This should ideally be a no-op that just returns `true`, but instead needs
8686
/// to be a recursive method that checks whether all the proper members can
8787
/// derive default or not, because of the limit rust has on 32 items as max in the
8888
/// array.
8989
pub trait CanDerivePartialEq {
90-
/// Return `true` if `Default` can be derived for this thing, `false`
90+
/// Return `true` if `PartialEq` can be derived for this thing, `false`
9191
/// otherwise.
9292
fn can_derive_partialeq(&self, ctx: &BindgenContext) -> bool;
9393
}
9494

95+
/// A trait that encapsulates the logic for whether or not we can derive `PartialOrd`
96+
/// for a given thing.
97+
///
98+
/// This should ideally be a no-op that just returns `true`, but instead needs
99+
/// 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
101+
/// array.
102+
pub trait CanDerivePartialOrd {
103+
/// Return `true` if `PartialOrd` can be derived for this thing, `false`
104+
/// otherwise.
105+
fn can_derive_partialord(&self, ctx: &BindgenContext) -> bool;
106+
}
107+
95108
/// A trait that encapsulates the logic for whether or not we can derive `Eq`
96109
/// for a given thing.
97110
///
@@ -118,12 +131,13 @@ pub trait CanTriviallyDeriveHash {
118131
fn can_trivially_derive_hash(&self) -> bool;
119132
}
120133

121-
/// A trait that encapsulates the logic for whether or not we can derive `PartialEq`.
134+
/// A trait that encapsulates the logic for whether or not we can derive `PartialEq`
135+
/// or `PartialOrd`.
122136
/// The difference between this trait and the CanDerivePartialEq is that the type
123137
/// implementing this trait cannot use recursion or lookup result from fix point
124138
/// analysis. It's a helper trait for fix point analysis.
125-
pub trait CanTriviallyDerivePartialEq {
126-
/// Return `true` if `PartialEq` can be derived for this thing, `false`
139+
pub trait CanTriviallyDerivePartialEqOrPartialOrd {
140+
/// Return `true` if `PartialEq` or `PartialOrd` can be derived for this thing, `false`
127141
/// otherwise.
128-
fn can_trivially_derive_partialeq(&self) -> bool;
142+
fn can_trivially_derive_partialeq_or_partialord(&self) -> bool;
129143
}

src/ir/function.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use super::ty::TypeKind;
99
use clang;
1010
use clang_sys::{self, CXCallingConv};
1111
use ir::derive::{CanTriviallyDeriveDebug, CanTriviallyDeriveHash,
12-
CanTriviallyDerivePartialEq};
12+
CanTriviallyDerivePartialEqOrPartialOrd};
1313
use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult};
1414
use quote;
1515
use std::io;
@@ -556,8 +556,8 @@ impl CanTriviallyDeriveHash for FunctionSig {
556556
}
557557
}
558558

559-
impl CanTriviallyDerivePartialEq for FunctionSig {
560-
fn can_trivially_derive_partialeq(&self) -> bool {
559+
impl CanTriviallyDerivePartialEqOrPartialOrd for FunctionSig {
560+
fn can_trivially_derive_partialeq_or_partialord(&self) -> bool {
561561
if self.argument_types.len() > RUST_DERIVE_FUNPTR_LIMIT {
562562
return false;
563563
}

src/ir/item.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +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, CanDerivePartialEq, CanDeriveEq};
9+
CanDeriveHash, CanDerivePartialOrd, CanDerivePartialEq,
10+
CanDeriveEq};
1011
use super::dot::DotAttributes;
1112
use super::function::{Function, FunctionKind};
1213
use super::item_kind::ItemKind;
@@ -330,17 +331,24 @@ impl CanDeriveHash for Item {
330331
}
331332
}
332333

334+
impl CanDerivePartialOrd for Item {
335+
fn can_derive_partialord(&self, ctx: &BindgenContext) -> bool {
336+
ctx.options().derive_partialord &&
337+
ctx.lookup_item_id_can_derive_partialeq_or_partialord(self.id())
338+
}
339+
}
340+
333341
impl CanDerivePartialEq for Item {
334342
fn can_derive_partialeq(&self, ctx: &BindgenContext) -> bool {
335343
ctx.options().derive_partialeq &&
336-
ctx.lookup_item_id_can_derive_partialeq(self.id())
344+
ctx.lookup_item_id_can_derive_partialeq_or_partialord(self.id())
337345
}
338346
}
339347

340348
impl CanDeriveEq for Item {
341349
fn can_derive_eq(&self, ctx: &BindgenContext) -> bool {
342350
ctx.options().derive_eq &&
343-
ctx.lookup_item_id_can_derive_partialeq(self.id()) &&
351+
ctx.lookup_item_id_can_derive_partialeq_or_partialord(self.id()) &&
344352
!ctx.lookup_item_id_has_float(&self.id())
345353
}
346354
}

src/ir/layout.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use super::derive::{CanTriviallyDeriveCopy, CanTriviallyDeriveDebug,
44
CanTriviallyDeriveDefault, CanTriviallyDeriveHash,
5-
CanTriviallyDerivePartialEq};
5+
CanTriviallyDerivePartialEqOrPartialOrd};
66
use super::ty::{RUST_DERIVE_IN_ARRAY_LIMIT, Type, TypeKind};
77
use clang;
88
use std::{cmp, mem};
@@ -138,8 +138,8 @@ impl CanTriviallyDeriveHash for Opaque {
138138
}
139139
}
140140

141-
impl CanTriviallyDerivePartialEq for Opaque {
142-
fn can_trivially_derive_partialeq(&self) -> bool {
141+
impl CanTriviallyDerivePartialEqOrPartialOrd for Opaque {
142+
fn can_trivially_derive_partialeq_or_partialord(&self) -> bool {
143143
self.array_size().map_or(false, |size| {
144144
size <= RUST_DERIVE_IN_ARRAY_LIMIT
145145
})

src/lib.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,10 @@ impl Builder {
261261
output_vector.push("--with-derive-hash".into());
262262
}
263263

264+
if self.options.derive_partialord {
265+
output_vector.push("--with-derive-partialord".into());
266+
}
267+
264268
if self.options.derive_partialeq {
265269
output_vector.push("--with-derive-partialeq".into());
266270
}
@@ -814,6 +818,12 @@ impl Builder {
814818
self
815819
}
816820

821+
/// Set whether `PartialOrd` should be derived by default.
822+
pub fn derive_partialord(mut self, doit: bool) -> Self {
823+
self.options.derive_partialord = doit;
824+
self
825+
}
826+
817827
/// Set whether `PartialEq` should be derived by default.
818828
/// If we don't compute partialeq, we also cannot compute
819829
/// eq. Set the derive_eq to `false` when doit is `false`.
@@ -1176,6 +1186,10 @@ struct BindgenOptions {
11761186
/// and types.
11771187
derive_hash: bool,
11781188

1189+
/// True if we should derive PartialOrd trait implementations for C/C++ structures
1190+
/// and types.
1191+
derive_partialord: bool,
1192+
11791193
/// True if we should derive PartialEq trait implementations for C/C++ structures
11801194
/// and types.
11811195
derive_partialeq: bool,
@@ -1325,6 +1339,7 @@ impl Default for BindgenOptions {
13251339
impl_debug: false,
13261340
derive_default: false,
13271341
derive_hash: false,
1342+
derive_partialord: false,
13281343
derive_partialeq: false,
13291344
derive_eq: false,
13301345
enable_cxx_namespaces: false,

src/options.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ where
8383
Arg::with_name("with-derive-partialeq")
8484
.long("with-derive-partialeq")
8585
.help("Derive partialeq on any type."),
86+
Arg::with_name("with-derive-partialord")
87+
.long("with-derive-partialord")
88+
.help("Derive partialord on any type."),
8689
Arg::with_name("with-derive-eq")
8790
.long("with-derive-eq")
8891
.help("Derive eq on any type. Enable this option also enables --with-derive-partialeq"),
@@ -340,6 +343,10 @@ where
340343
builder = builder.derive_partialeq(true);
341344
}
342345

346+
if matches.is_present("with-derive-partialord") {
347+
builder = builder.derive_partialord(true);
348+
}
349+
343350
if matches.is_present("with-derive-eq") {
344351
builder = builder.derive_eq(true);
345352
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55

66

77

8-
/// A struct containing a struct containing a float that cannot derive hash/eq but can derive partial eq.
8+
/// A struct containing a struct containing a float that cannot derive hash/eq but can derive partialeq and partialord
99
#[repr(C)]
10-
#[derive(Debug, Default, Copy, PartialEq)]
10+
#[derive(Debug, Default, Copy, PartialOrd, PartialEq)]
1111
pub struct foo {
1212
pub bar: foo__bindgen_ty_1,
1313
}
1414
#[repr(C)]
15-
#[derive(Debug, Default, Copy, PartialEq)]
15+
#[derive(Debug, Default, Copy, PartialOrd, PartialEq)]
1616
pub struct foo__bindgen_ty_1 {
1717
pub a: f32,
1818
pub b: f32,

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66

77

8-
/// A struct containing an array of floats that cannot derive hash/eq but can derive partialeq.
8+
/// A struct containing an array of floats that cannot derive hash/eq but can derive partialeq and partialord
99
#[repr(C)]
10-
#[derive(Debug, Default, Copy, PartialEq)]
10+
#[derive(Debug, Default, Copy, PartialOrd, PartialEq)]
1111
pub struct foo {
1212
pub bar: [f32; 3usize],
1313
}

0 commit comments

Comments
 (0)