From 230545e7c9d135bbf338642b69ac01c5d1e0bf2d Mon Sep 17 00:00:00 2001 From: Sergey Pepyakin Date: Sun, 29 Oct 2017 17:50:02 +0300 Subject: [PATCH] Refactor derive_partialeq_or_partialord. --- src/codegen/mod.rs | 7 +- .../derive_partialeq_or_partialord.rs | 197 ++++++++---------- src/ir/context.rs | 20 +- src/ir/derive.rs | 79 +++++-- src/ir/function.rs | 6 +- src/ir/item.rs | 25 +-- src/ir/layout.rs | 6 +- 7 files changed, 185 insertions(+), 155 deletions(-) diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 53ed24ff08..d36decb0a0 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -17,7 +17,7 @@ use ir::comp::{Base, Bitfield, BitfieldUnit, CompInfo, CompKind, Field, use ir::context::{BindgenContext, ItemId}; use ir::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault, CanDeriveHash, CanDerivePartialOrd, CanDeriveOrd, - CanDerivePartialEq, CanDeriveEq, CannotDeriveReason}; + CanDerivePartialEq, CanDeriveEq, CanDerive}; use ir::dot; use ir::enum_ty::{Enum, EnumVariant, EnumVariantValue}; use ir::function::{Abi, Function, FunctionSig, Linkage}; @@ -1676,10 +1676,7 @@ impl CodeGenerator for CompInfo { needs_partialeq_impl = ctx.options().derive_partialeq && ctx.options().impl_partialeq && - ctx.lookup_can_derive_partialeq_or_partialord(item.id()) - .map_or(true, |x| { - x == CannotDeriveReason::ArrayTooLarge - }); + ctx.lookup_can_derive_partialeq_or_partialord(item.id()) == CanDerive::ArrayTooLarge; } if item.can_derive_eq(ctx) { diff --git a/src/ir/analysis/derive_partialeq_or_partialord.rs b/src/ir/analysis/derive_partialeq_or_partialord.rs index f54650dd02..92861341b2 100644 --- a/src/ir/analysis/derive_partialeq_or_partialord.rs +++ b/src/ir/analysis/derive_partialeq_or_partialord.rs @@ -4,12 +4,13 @@ use super::{ConstrainResult, MonotoneFramework, generate_dependencies}; use ir::comp::CompKind; use ir::context::{BindgenContext, ItemId}; -use ir::derive::{CanTriviallyDerivePartialEqOrPartialOrd, CanDerive, CannotDeriveReason}; +use ir::derive::{CanTriviallyDerivePartialEqOrPartialOrd, CanDerive}; use ir::item::{Item, IsOpaque}; use ir::traversal::{EdgeKind, Trace}; use ir::ty::RUST_DERIVE_IN_ARRAY_LIMIT; use ir::ty::{TypeKind, Type}; use std::collections::HashMap; +use std::collections::hash_map::Entry; /// An analysis that finds for each IR item whether `PartialEq`/`PartialOrd` /// cannot be derived. @@ -21,7 +22,7 @@ use std::collections::HashMap; /// type and check whether it can be derived using trivial checks. /// /// * If T is Array type, `PartialEq` or partialord cannot be derived if the array is incomplete, if the length of -/// the array is larger than the limit, or the type of data the array contains cannot derive +/// the array is larger than the limit, or the type of data the array contains cannot derive /// `PartialEq`/`PartialOrd`. /// /// * If T is a type alias, a templated alias or an indirection to another type, @@ -42,9 +43,9 @@ use std::collections::HashMap; pub struct CannotDerivePartialEqOrPartialOrd<'ctx> { ctx: &'ctx BindgenContext, - // The incremental result of this analysis's computation. Everything in this - // set cannot derive `PartialEq`/`PartialOrd`. - cannot_derive_partialeq_or_partialord: HashMap, + // The incremental result of this analysis's computation. + // Contains information whether particular item can derive `PartialEq`/`PartialOrd`. + can_derive_partialeq_or_partialord: HashMap, // Dependencies saying that if a key ItemId has been inserted into the // `cannot_derive_partialeq_or_partialord` set, then each of the ids @@ -83,31 +84,36 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> { fn insert>( &mut self, id: Id, - reason: CannotDeriveReason, + can_derive: CanDerive, ) -> ConstrainResult { let id = id.into(); - trace!( - "inserting {:?} into the cannot_derive_partialeq_or_partialord because {:?}", - id, - reason - ); - let existing = self.cannot_derive_partialeq_or_partialord - .insert(id, reason); - assert!(can_supersede(existing, Some(reason))); - ConstrainResult::Changed + trace!("inserting {:?} can_derive={:?}", id, can_derive); + + if let CanDerive::Yes = can_derive { + return ConstrainResult::Same; + } + + match self.can_derive_partialeq_or_partialord.entry(id) { + Entry::Occupied(mut entry) => if *entry.get() < can_derive { + entry.insert(can_derive); + ConstrainResult::Changed + } else { + ConstrainResult::Same + }, + Entry::Vacant(entry) => { + entry.insert(can_derive); + ConstrainResult::Changed + } + } } - fn constrain_type( - &mut self, - item: &Item, - ty: &Type, - ) -> Option { + fn constrain_type(&mut self, item: &Item, ty: &Type) -> CanDerive { if !self.ctx.whitelisted_items().contains(&item.id()) { - return Some(CannotDeriveReason::Other); + return CanDerive::No; } if self.ctx.no_partialeq_by_name(&item) { - return Some(CannotDeriveReason::Other); + return CanDerive::No; } trace!("ty: {:?}", ty); @@ -118,7 +124,7 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> { trace!( " cannot derive `PartialEq`/`PartialOrd` for Rust unions" ); - return Some(CannotDeriveReason::Other); + return CanDerive::No; } let layout_can_derive = ty.layout(self.ctx) @@ -126,20 +132,19 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> { l.opaque().can_trivially_derive_partialeq_or_partialord() }); - return match layout_can_derive { + match layout_can_derive { CanDerive::Yes => { trace!( " we can trivially derive `PartialEq`/`PartialOrd` for the layout" ); - None } - CanDerive::No(reason) => { + _ => { trace!( " we cannot derive `PartialEq`/`PartialOrd` for the layout" ); - Some(reason) } }; + return layout_can_derive; } match *ty.kind() { @@ -161,33 +166,37 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> { trace!( " simple type that can always derive `PartialEq`/`PartialOrd`" ); - return None; + return CanDerive::Yes; } TypeKind::Array(t, len) => { - if self.cannot_derive_partialeq_or_partialord.contains_key(&t.into()) { + let inner_type = self.can_derive_partialeq_or_partialord + .get(&t.into()) + .cloned() + .unwrap_or(CanDerive::Yes); + if inner_type != CanDerive::Yes { trace!( " arrays of T for which we cannot derive `PartialEq`/`PartialOrd` \ also cannot derive `PartialEq`/`PartialOrd`" ); - return Some(CannotDeriveReason::Other); + return CanDerive::No; } if len == 0 { trace!( " cannot derive `PartialEq`/`PartialOrd` for incomplete arrays" ); - return Some(CannotDeriveReason::Other); + return CanDerive::No; } else if len <= RUST_DERIVE_IN_ARRAY_LIMIT { trace!( " array is small enough to derive `PartialEq`/`PartialOrd`" ); - return None; + return CanDerive::Yes; } else { trace!( " array is too large to derive `PartialEq`/`PartialOrd`" ); - return Some(CannotDeriveReason::ArrayTooLarge); + return CanDerive::ArrayTooLarge; } } @@ -195,30 +204,30 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> { let inner_type = self.ctx.resolve_type(inner).canonical_type(self.ctx); if let TypeKind::Function(ref sig) = *inner_type.kind() { - if let CanDerive::No(_) = - sig.can_trivially_derive_partialeq_or_partialord() + if sig.can_trivially_derive_partialeq_or_partialord() + != CanDerive::Yes { trace!( " function pointer that can't trivially derive `PartialEq`/`PartialOrd`" ); - return Some(CannotDeriveReason::Other); + return CanDerive::No; } } trace!(" pointers can derive `PartialEq`/`PartialOrd`"); - return None; + return CanDerive::Yes; } TypeKind::Function(ref sig) => { - if let CanDerive::No(_) = - sig.can_trivially_derive_partialeq_or_partialord() + if sig.can_trivially_derive_partialeq_or_partialord() + != CanDerive::Yes { trace!( " function that can't trivially derive `PartialEq`/`PartialOrd`" ); - return Some(CannotDeriveReason::Other); + return CanDerive::No; } trace!(" function can derive `PartialEq`/`PartialOrd`"); - return None; + return CanDerive::Yes; } TypeKind::Comp(ref info) => { @@ -232,30 +241,27 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> { trace!( " cannot derive `PartialEq`/`PartialOrd` for Rust unions" ); - return Some(CannotDeriveReason::Other); + return CanDerive::No; } - let layout_can_derive = ty.layout(self.ctx).map_or( - CanDerive::Yes, - |l| { + let layout_can_derive = + ty.layout(self.ctx).map_or(CanDerive::Yes, |l| { l.opaque() .can_trivially_derive_partialeq_or_partialord() - }, - ); - return match layout_can_derive { + }); + match layout_can_derive { CanDerive::Yes => { trace!( " union layout can trivially derive `PartialEq`/`PartialOrd`" ); - None } - CanDerive::No(reason) => { + _ => { trace!( " union layout cannot derive `PartialEq`/`PartialOrd`" ); - Some(reason) } }; + return layout_can_derive; } return self.constrain_join(item); } @@ -273,8 +279,8 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> { } } - fn constrain_join(&mut self, item: &Item) -> Option { - let mut candidate = None; + fn constrain_join(&mut self, item: &Item) -> CanDerive { + let mut candidate = CanDerive::Yes; item.trace( self.ctx, @@ -286,13 +292,12 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> { return; } - let reason = self.cannot_derive_partialeq_or_partialord + let can_derive = self.can_derive_partialeq_or_partialord .get(&sub_id) - .cloned(); + .cloned() + .unwrap_or_default(); - if can_supersede(candidate, reason) { - candidate = reason; - } + candidate |= can_derive; }, &(), ); @@ -301,45 +306,20 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> { } } -/// Check if the one reason could supersede another. -/// -/// To keep this analysis monotone we should go only in one direction. -/// If the abscence of the reason is at the bottom and `CannotDeriveReason::Other` -/// is at the top, then we can only go upwards. -/// -/// Other -/// ^ -/// | -/// ArrayTooLarge -/// ^ -/// | -/// None -/// -fn can_supersede(from: Option, to: Option) -> bool { - fn rank(maybe_reason: Option) -> usize { - match maybe_reason { - None => 0, - Some(CannotDeriveReason::ArrayTooLarge) => 1, - Some(CannotDeriveReason::Other) => 2, - } - } - rank(from) <= rank(to) -} - impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> { type Node = ItemId; type Extra = &'ctx BindgenContext; - type Output = HashMap; + type Output = HashMap; fn new( ctx: &'ctx BindgenContext, ) -> CannotDerivePartialEqOrPartialOrd<'ctx> { - let cannot_derive_partialeq_or_partialord = HashMap::new(); + let can_derive_partialeq_or_partialord = HashMap::new(); let dependencies = generate_dependencies(ctx, Self::consider_edge); CannotDerivePartialEqOrPartialOrd { ctx, - cannot_derive_partialeq_or_partialord, + can_derive_partialeq_or_partialord, dependencies, } } @@ -365,43 +345,40 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> { .collect() } - fn constrain(&mut self, id: ItemId) -> ConstrainResult { + fn constrain(&mut self, id: ItemId) -> ConstrainResult { trace!("constrain: {:?}", id); - if let Some(CannotDeriveReason::Other) = - self.cannot_derive_partialeq_or_partialord.get(&id).cloned() + if let Some(CanDerive::No) = + self.can_derive_partialeq_or_partialord.get(&id).cloned() { - trace!(" already know it cannot derive `PartialEq`/`PartialOrd`"); + trace!( + " already know it cannot derive `PartialEq`/`PartialOrd`" + ); return ConstrainResult::Same; } let item = self.ctx.resolve_item(id); - let maybe_reason = match item.as_type() { + let can_derive = match item.as_type() { Some(ty) => { - self.constrain_type(item, ty).or_else(|| { - if ty.layout(self.ctx).map_or(false, |l| { - l.align > RUST_DERIVE_IN_ARRAY_LIMIT - }) + let mut can_derive = self.constrain_type(item, ty); + if let CanDerive::Yes = can_derive { + if ty.layout(self.ctx) + .map_or(false, |l| l.align > RUST_DERIVE_IN_ARRAY_LIMIT) { // We have to be conservative: the struct *could* have enough // padding that we emit an array that is longer than // `RUST_DERIVE_IN_ARRAY_LIMIT`. If we moved padding calculations // into the IR and computed them before this analysis, then we could // be precise rather than conservative here. - Some(CannotDeriveReason::ArrayTooLarge) - } else { - None + can_derive = CanDerive::ArrayTooLarge; } - }) + } + can_derive } None => self.constrain_join(item), }; - if let Some(reason) = maybe_reason { - self.insert(id, reason) - } else { - ConstrainResult::Same - } + self.insert(id, can_derive) } fn each_depending_on(&self, id: ItemId, mut f: F) @@ -417,8 +394,16 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> { } } -impl<'ctx> From> for HashMap { +impl<'ctx> From> + for HashMap { fn from(analysis: CannotDerivePartialEqOrPartialOrd<'ctx>) -> Self { - analysis.cannot_derive_partialeq_or_partialord + extra_assert!( + analysis + .can_derive_partialeq_or_partialord + .values() + .all(|v| { *v != CanDerive::Yes }) + ); + + analysis.can_derive_partialeq_or_partialord } } diff --git a/src/ir/context.rs b/src/ir/context.rs index 138a69b988..b2ebb929ef 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -8,7 +8,7 @@ use super::analysis::{CannotDeriveCopy, CannotDeriveDebug, CannotDeriveDefault, SizednessResult, analyze}; use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault, CanDeriveHash, CanDerivePartialOrd, CanDeriveOrd, - CanDerivePartialEq, CanDeriveEq, CannotDeriveReason}; + CanDerivePartialEq, CanDeriveEq, CanDerive}; use super::int::IntKind; use super::item::{IsOpaque, Item, ItemAncestors, ItemCanonicalPath, ItemSet}; use super::item_kind::ItemKind; @@ -251,7 +251,7 @@ where { fn can_derive_partialord(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_partialord && - ctx.lookup_can_derive_partialeq_or_partialord(*self).is_none() + ctx.lookup_can_derive_partialeq_or_partialord(*self) == CanDerive::Yes } } @@ -261,7 +261,7 @@ where { fn can_derive_partialeq(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_partialeq && - ctx.lookup_can_derive_partialeq_or_partialord(*self).is_none() + ctx.lookup_can_derive_partialeq_or_partialord(*self) == CanDerive::Yes } } @@ -271,7 +271,7 @@ where { fn can_derive_eq(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_eq && - ctx.lookup_can_derive_partialeq_or_partialord(*self).is_none() && + ctx.lookup_can_derive_partialeq_or_partialord(*self) == CanDerive::Yes && !ctx.lookup_has_float(*self) } } @@ -282,7 +282,7 @@ where { fn can_derive_ord(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_ord && - ctx.lookup_can_derive_partialeq_or_partialord(*self).is_none() && + ctx.lookup_can_derive_partialeq_or_partialord(*self) == CanDerive::Yes && !ctx.lookup_has_float(*self) } } @@ -427,7 +427,7 @@ pub struct BindgenContext { /// This is populated when we enter codegen by /// `compute_cannot_derive_partialord_partialeq_or_eq` and is always `None` /// before that and `Some` after. - cannot_derive_partialeq_or_partialord: Option>, + cannot_derive_partialeq_or_partialord: Option>, /// The sizedness of types. /// @@ -2419,7 +2419,7 @@ impl BindgenContext { } /// Look up whether the item with `id` can derive `Partial{Eq,Ord}`. - pub fn lookup_can_derive_partialeq_or_partialord>(&self, id: Id) -> Option { + pub fn lookup_can_derive_partialeq_or_partialord>(&self, id: Id) -> CanDerive { let id = id.into(); assert!( self.in_codegen_phase(), @@ -2428,7 +2428,11 @@ impl BindgenContext { // Look up the computed value for whether the item with `id` can // derive partialeq or not. - self.cannot_derive_partialeq_or_partialord.as_ref().unwrap().get(&id).cloned() + self.cannot_derive_partialeq_or_partialord.as_ref() + .unwrap() + .get(&id) + .cloned() + .unwrap_or(CanDerive::Yes) } /// Look up whether the item with `id` can derive `Copy` or not. diff --git a/src/ir/derive.rs b/src/ir/derive.rs index 52e611336f..b0a6912f8d 100644 --- a/src/ir/derive.rs +++ b/src/ir/derive.rs @@ -13,6 +13,9 @@ use super::context::BindgenContext; +use std::cmp; +use std::ops; + /// A trait that encapsulates the logic for whether or not we can derive `Debug` /// for a given thing. pub trait CanDeriveDebug { @@ -115,29 +118,79 @@ pub trait CanTriviallyDeriveHash { /// derive `PartialEq` or `PartialOrd` without looking at any other types or /// results of fix point analyses. This is a helper for the fix point analysis. pub trait CanTriviallyDerivePartialEqOrPartialOrd { - /// Return `true` if `PartialEq` or `PartialOrd` can trivially be derived - /// for this thing, `false` otherwise. + /// Return `Yes` if `PartialEq` or `PartialOrd` can trivially be derived + /// for this thing. fn can_trivially_derive_partialeq_or_partialord(&self) -> CanDerive; } -/// Reason why exactly we cannot automatically derive a trait. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum CannotDeriveReason { +/// Whether it is possible or not to automatically derive trait for an item. +/// +/// ```ignore +/// No +/// ^ +/// | +/// ArrayTooLarge +/// ^ +/// | +/// Yes +/// ``` +/// +/// Initially we assume that we can derive trait for all types and then +/// update our understanding as we learn more about each type. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord)] +pub enum CanDerive { + /// No, we cannot. + No, + /// The only thing that stops us from automatically deriving is that /// array with more than maximum number of elements is used. /// /// This means we probably can "manually" implement such trait. ArrayTooLarge, - /// Any other reason. - Other, + /// Yes, we can derive automatically. + Yes, } -/// Whether it is possible or not to derive trait automatically. -pub enum CanDerive { - /// Yes, we can! - Yes, +impl Default for CanDerive { + fn default() -> CanDerive { + CanDerive::Yes + } +} + +impl cmp::PartialOrd for CanDerive { + fn partial_cmp(&self, rhs: &Self) -> Option { + use self::CanDerive::*; + + let ordering = match (*self, *rhs) { + (x, y) if x == y => cmp::Ordering::Equal, + (No, _) => cmp::Ordering::Greater, + (_, No) => cmp::Ordering::Less, + (ArrayTooLarge, _) => cmp::Ordering::Greater, + (_, ArrayTooLarge) => cmp::Ordering::Less, + _ => unreachable!() + }; + Some(ordering) + } +} + +impl CanDerive { + /// Take the least upper bound of `self` and `rhs`. + pub fn join(self, rhs: Self) -> Self { + cmp::max(self, rhs) + } +} + +impl ops::BitOr for CanDerive { + type Output = Self; + + fn bitor(self, rhs: Self) -> Self::Output { + self.join(rhs) + } +} - /// No, we cannot. Contains reason why exactly we can't derive. - No(CannotDeriveReason) +impl ops::BitOrAssign for CanDerive { + fn bitor_assign(&mut self, rhs: Self) { + *self = self.join(rhs) + } } diff --git a/src/ir/function.rs b/src/ir/function.rs index 60a7effd77..62792484f3 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -9,7 +9,7 @@ use super::ty::TypeKind; use clang; use clang_sys::{self, CXCallingConv}; use ir::derive::{CanTriviallyDeriveDebug, CanTriviallyDeriveHash, - CanTriviallyDerivePartialEqOrPartialOrd, CanDerive, CannotDeriveReason}; + CanTriviallyDerivePartialEqOrPartialOrd, CanDerive}; use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult}; use quote; use std::io; @@ -566,12 +566,12 @@ impl CanTriviallyDeriveHash for FunctionSig { impl CanTriviallyDerivePartialEqOrPartialOrd for FunctionSig { fn can_trivially_derive_partialeq_or_partialord(&self) -> CanDerive { if self.argument_types.len() > RUST_DERIVE_FUNPTR_LIMIT { - return CanDerive::No(CannotDeriveReason::Other); + return CanDerive::No; } match self.abi { Abi::C | Abi::Unknown(..) => CanDerive::Yes, - _ => CanDerive::No(CannotDeriveReason::Other), + _ => CanDerive::No, } } } diff --git a/src/ir/item.rs b/src/ir/item.rs index 9ed7267d7f..d863d9077b 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -319,58 +319,49 @@ impl Trace for Item { impl CanDeriveDebug for Item { fn can_derive_debug(&self, ctx: &BindgenContext) -> bool { - ctx.options().derive_debug && - ctx.lookup_can_derive_debug(self.id()) + self.id().can_derive_debug(ctx) } } impl CanDeriveDefault for Item { fn can_derive_default(&self, ctx: &BindgenContext) -> bool { - ctx.options().derive_default && - ctx.lookup_can_derive_default(self.id()) + self.id().can_derive_default(ctx) } } impl<'a> CanDeriveCopy<'a> for Item { fn can_derive_copy(&self, ctx: &BindgenContext) -> bool { - ctx.lookup_can_derive_copy(self.id()) + self.id().can_derive_copy(ctx) } } impl CanDeriveHash for Item { fn can_derive_hash(&self, ctx: &BindgenContext) -> bool { - ctx.options().derive_hash && - ctx.lookup_can_derive_hash(self.id()) + self.id().can_derive_hash(ctx) } } impl CanDerivePartialOrd for Item { fn can_derive_partialord(&self, ctx: &BindgenContext) -> bool { - ctx.options().derive_partialord && - ctx.lookup_can_derive_partialeq_or_partialord(self.id()).is_none() + self.id().can_derive_partialord(ctx) } } impl CanDerivePartialEq for Item { fn can_derive_partialeq(&self, ctx: &BindgenContext) -> bool { - ctx.options().derive_partialeq && - ctx.lookup_can_derive_partialeq_or_partialord(self.id()).is_none() + self.id().can_derive_partialeq(ctx) } } impl CanDeriveEq for Item { fn can_derive_eq(&self, ctx: &BindgenContext) -> bool { - ctx.options().derive_eq && - ctx.lookup_can_derive_partialeq_or_partialord(self.id()).is_none() && - !ctx.lookup_has_float(self.id()) + self.id().can_derive_eq(ctx) } } impl CanDeriveOrd for Item { fn can_derive_ord(&self, ctx: &BindgenContext) -> bool { - ctx.options().derive_ord && - ctx.lookup_can_derive_partialeq_or_partialord(self.id()).is_none() && - !ctx.lookup_has_float(self.id()) + self.id().can_derive_ord(ctx) } } diff --git a/src/ir/layout.rs b/src/ir/layout.rs index ac875ca42b..0c99c7e77c 100644 --- a/src/ir/layout.rs +++ b/src/ir/layout.rs @@ -2,7 +2,7 @@ use super::derive::{CanTriviallyDeriveCopy, CanTriviallyDeriveDebug, CanTriviallyDeriveDefault, CanTriviallyDeriveHash, - CanTriviallyDerivePartialEqOrPartialOrd, CanDerive, CannotDeriveReason}; + CanTriviallyDerivePartialEqOrPartialOrd, CanDerive}; use super::ty::{RUST_DERIVE_IN_ARRAY_LIMIT, Type, TypeKind}; use clang; use std::{cmp, mem}; @@ -141,11 +141,11 @@ impl CanTriviallyDeriveHash for Opaque { impl CanTriviallyDerivePartialEqOrPartialOrd for Opaque { fn can_trivially_derive_partialeq_or_partialord(&self) -> CanDerive { - self.array_size().map_or(CanDerive::No(CannotDeriveReason::Other), |size| { + self.array_size().map_or(CanDerive::No, |size| { if size <= RUST_DERIVE_IN_ARRAY_LIMIT { CanDerive::Yes } else { - CanDerive::No(CannotDeriveReason::ArrayTooLarge) + CanDerive::ArrayTooLarge } }) }