Implement fast path for derive(PartialOrd)

This commit is contained in:
Makai
2026-04-21 20:46:59 +08:00
parent b954122bbe
commit c9a560b30d
14 changed files with 111 additions and 276 deletions
@@ -1,4 +1,4 @@
use rustc_ast::{ExprKind, ItemKind, MetaItem, PatKind, Safety};
use rustc_ast::{ExprKind, ItemKind, MetaItem, PatKind, Safety, ast};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::{Ident, Span, sym};
use thin_vec::thin_vec;
@@ -41,6 +41,35 @@ pub(crate) fn expand_deriving_partial_ord(
} else {
true
};
let substructure = combine_substructure(Box::new(|cx, span, substr| {
cs_partial_cmp(cx, span, substr, discr_then_data)
}));
let (is_simple, substructure) = match item {
Annotatable::Item(annitem) => match &annitem.kind {
ItemKind::Struct(_, ast::Generics { params, .. }, _)
| ItemKind::Enum(_, ast::Generics { params, .. }, _)
if let container_id = cx.current_expansion.id.expn_data().parent.expect_local()
&& cx.resolver.has_derive_ord(container_id)
&& !params
.iter()
.any(|param| matches!(param.kind, ast::GenericParamKind::Type { .. })) =>
{
(
true,
combine_substructure(Box::new(|cx, span, _| {
cs_partial_cmp_simple(
cx,
span,
cx.expr_ident(span, Ident::new(sym::other, span)),
)
})),
)
}
_ => (false, substructure),
},
_ => (false, substructure),
};
let partial_cmp_def = MethodDef {
name: sym::partial_cmp,
generics: Bounds::empty(),
@@ -49,9 +78,7 @@ pub(crate) fn expand_deriving_partial_ord(
ret_ty,
attributes: thin_vec![cx.attr_word(sym::inline, span)],
fieldless_variants_strategy: FieldlessVariantsStrategy::Unify,
combine_substructure: combine_substructure(Box::new(|cx, span, substr| {
cs_partial_cmp(cx, span, substr, discr_then_data)
})),
combine_substructure: substructure,
};
let trait_def = TraitDef {
@@ -68,7 +95,21 @@ pub(crate) fn expand_deriving_partial_ord(
safety: Safety::Default,
document: true,
};
trait_def.expand(cx, mitem, item, push)
trait_def.expand_ext(cx, mitem, item, push, is_simple)
}
// Special case for the type deriving both `PartialOrd` and `Ord`. Builds:
// ```
// Some(self.cmp(other))
// ```
fn cs_partial_cmp_simple(cx: &ExtCtxt<'_>, span: Span, other_expr: Box<ast::Expr>) -> BlockOrExpr {
let cmp_expr = cx.expr_method_call(
span,
cx.expr_self(span),
Ident::new(sym::cmp, span),
thin_vec![other_expr],
);
BlockOrExpr::new_expr(cx.expr_some(span, cmp_expr))
}
fn cs_partial_cmp(
@@ -98,7 +139,8 @@ fn cs_partial_cmp(
|cx, fold| match fold {
CsFold::Single(field) => {
let [other_expr] = &field.other_selflike_exprs[..] else {
cx.dcx().span_bug(field.span, "not exactly 2 arguments in `derive(Ord)`");
cx.dcx()
.span_bug(field.span, "not exactly 2 arguments in `derive(PartialOrd)`");
};
let args = thin_vec![field.self_expr.clone(), other_expr.clone()];
cx.expr_call_global(field.span, partial_cmp_path.clone(), args)
+2
View File
@@ -1117,6 +1117,8 @@ fn resolve_macro_invocation(
// Resolver interfaces for specific built-in macros.
/// Does `#[derive(...)]` attribute with the given `ExpnId` have built-in `Copy` inside it?
fn has_derive_copy(&self, expn_id: LocalExpnId) -> bool;
/// Does `#[derive(...)]` attribute with the given `ExpnId` have built-in `Ord` inside it?
fn has_derive_ord(&self, expn_id: LocalExpnId) -> bool;
/// Resolve paths inside the `#[derive(...)]` attribute with the given `ExpnId`.
fn resolve_derives(
&mut self,
+4
View File
@@ -1323,7 +1323,10 @@ fn span(&self) -> Span {
struct DeriveData {
resolutions: Vec<DeriveResolution>,
helper_attrs: Vec<(usize, IdentKey, Span)>,
// if this list keeps getting extended, we could use `bitflags`,
// something like what [`rustc_type_ir::flags::TypeFlags`] is doing.
has_derive_copy: bool,
has_derive_ord: bool,
}
pub struct ResolverOutputs<'tcx> {
@@ -1467,6 +1470,7 @@ pub struct Resolver<'ra, 'tcx> {
/// Derive macros cannot modify the item themselves and have to store the markers in the global
/// context, so they attach the markers to derive container IDs using this resolver table.
containers_deriving_copy: FxHashSet<LocalExpnId> = default::fx_hash_set(),
containers_deriving_ord: FxHashSet<LocalExpnId> = default::fx_hash_set(),
/// Parent scopes in which the macros were invoked.
/// FIXME: `derives` are missing in these parent scopes and need to be taken from elsewhere.
invocation_parent_scopes: FxHashMap<LocalExpnId, ParentScope<'ra>> = default::fx_hash_map(),
+12
View File
@@ -379,6 +379,10 @@ fn has_derive_copy(&self, expn_id: LocalExpnId) -> bool {
self.containers_deriving_copy.contains(&expn_id)
}
fn has_derive_ord(&self, expn_id: LocalExpnId) -> bool {
self.containers_deriving_ord.contains(&expn_id)
}
fn resolve_derives(
&mut self,
expn_id: LocalExpnId,
@@ -398,6 +402,7 @@ fn resolve_derives(
resolutions: derive_paths(),
helper_attrs: Vec::new(),
has_derive_copy: false,
has_derive_ord: false,
});
let parent_scope = self.invocation_parent_scopes[&expn_id];
for (i, resolution) in entry.resolutions.iter_mut().enumerate() {
@@ -420,6 +425,7 @@ fn resolve_derives(
);
}
entry.has_derive_copy |= ext.builtin_name == Some(sym::Copy);
entry.has_derive_ord |= ext.builtin_name == Some(sym::Ord);
ext
}
Ok(_) | Err(Determinacy::Determined) => self.dummy_ext(MacroKind::Derive),
@@ -455,6 +461,12 @@ fn resolve_derives(
if entry.has_derive_copy || self.has_derive_copy(parent_scope.expansion) {
self.containers_deriving_copy.insert(expn_id);
}
// Similar to the above `Copy` and `Clone` case, the code generated for
// `derive(PartialOrd)` changes if `derive(Ord)` is also present.
// FIXME(makai410): this also doesn't work with `#[derive(PartialOrd)] #[derive(Ord)]`.
if entry.has_derive_ord || self.has_derive_ord(parent_scope.expansion) {
self.containers_deriving_ord.insert(expn_id);
}
assert!(self.derive_data.is_empty());
self.derive_data = derive_data;
Ok(())
@@ -10,8 +10,8 @@
// EMIT_MIR derived_ord_debug.{impl#1}-cmp.runtime-optimized.after.mir
// CHECK-LABEL: partial_cmp(_1: &MultiField, _2: &MultiField) -> Option<std::cmp::Ordering>
// CHECK: = <char as PartialOrd>::partial_cmp(
// CHECK: = <i16 as PartialOrd>::partial_cmp(
// CHECK: = <MultiField as Ord>::cmp(
// CHECK: = Option::<std::cmp::Ordering>::Some(
// CHECK-LABEL: cmp(_1: &MultiField, _2: &MultiField) -> std::cmp::Ordering
// CHECK: = <char as Ord>::cmp(
@@ -4,49 +4,14 @@ fn <impl at $DIR/derived_ord_debug.rs:6:10: 6:20>::partial_cmp(_1: &MultiField,
debug self => _1;
debug other => _2;
let mut _0: std::option::Option<std::cmp::Ordering>;
let _3: &char;
let _4: &char;
let mut _5: std::option::Option<std::cmp::Ordering>;
let mut _6: isize;
let mut _7: i8;
let _8: &i16;
let _9: &i16;
scope 1 {
debug cmp => _5;
}
let mut _3: std::cmp::Ordering;
bb0: {
_3 = &((*_1).0: char);
_4 = &((*_2).0: char);
_5 = <char as PartialOrd>::partial_cmp(copy _3, copy _4) -> [return: bb1, unwind continue];
_3 = <MultiField as Ord>::cmp(copy _1, copy _2) -> [return: bb1, unwind continue];
}
bb1: {
_6 = discriminant(_5);
switchInt(move _6) -> [1: bb2, 0: bb4, otherwise: bb6];
}
bb2: {
_7 = discriminant(((_5 as Some).0: std::cmp::Ordering));
switchInt(move _7) -> [0: bb3, otherwise: bb4];
}
bb3: {
_8 = &((*_1).1: i16);
_9 = &((*_2).1: i16);
_0 = <i16 as PartialOrd>::partial_cmp(copy _8, copy _9) -> [return: bb5, unwind continue];
}
bb4: {
_0 = copy _5;
goto -> bb5;
}
bb5: {
_0 = Option::<std::cmp::Ordering>::Some(move _3);
return;
}
bb6: {
unreachable;
}
}
+13 -96
View File
@@ -72,7 +72,7 @@ impl ::core::cmp::PartialOrd for Empty {
#[inline]
fn partial_cmp(&self, other: &Empty)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ordering::Equal)
::core::option::Option::Some(self.cmp(other))
}
}
#[automatically_derived]
@@ -151,11 +151,7 @@ impl ::core::cmp::PartialOrd for Point {
#[inline]
fn partial_cmp(&self, other: &Point)
-> ::core::option::Option<::core::cmp::Ordering> {
match ::core::cmp::PartialOrd::partial_cmp(&self.x, &other.x) {
::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
::core::cmp::PartialOrd::partial_cmp(&self.y, &other.y),
cmp => cmp,
}
::core::option::Option::Some(self.cmp(other))
}
}
#[automatically_derived]
@@ -239,13 +235,7 @@ impl ::core::cmp::PartialOrd for PackedPoint {
#[inline]
fn partial_cmp(&self, other: &PackedPoint)
-> ::core::option::Option<::core::cmp::Ordering> {
match ::core::cmp::PartialOrd::partial_cmp(&{ self.x }, &{ other.x })
{
::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
::core::cmp::PartialOrd::partial_cmp(&{ self.y },
&{ other.y }),
cmp => cmp,
}
::core::option::Option::Some(self.cmp(other))
}
}
#[automatically_derived]
@@ -322,7 +312,7 @@ impl ::core::cmp::PartialOrd for TupleSingleField {
#[inline]
fn partial_cmp(&self, other: &TupleSingleField)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
::core::option::Option::Some(self.cmp(other))
}
}
#[automatically_derived]
@@ -397,7 +387,7 @@ impl ::core::cmp::PartialOrd for SingleField {
#[inline]
fn partial_cmp(&self, other: &SingleField)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::cmp::PartialOrd::partial_cmp(&self.foo, &other.foo)
::core::option::Option::Some(self.cmp(other))
}
}
#[automatically_derived]
@@ -502,47 +492,7 @@ impl ::core::cmp::PartialOrd for Big {
#[inline]
fn partial_cmp(&self, other: &Big)
-> ::core::option::Option<::core::cmp::Ordering> {
match ::core::cmp::PartialOrd::partial_cmp(&self.b1, &other.b1) {
::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
match ::core::cmp::PartialOrd::partial_cmp(&self.b2,
&other.b2) {
::core::option::Option::Some(::core::cmp::Ordering::Equal)
=>
match ::core::cmp::PartialOrd::partial_cmp(&self.b3,
&other.b3) {
::core::option::Option::Some(::core::cmp::Ordering::Equal)
=>
match ::core::cmp::PartialOrd::partial_cmp(&self.b4,
&other.b4) {
::core::option::Option::Some(::core::cmp::Ordering::Equal)
=>
match ::core::cmp::PartialOrd::partial_cmp(&self.b5,
&other.b5) {
::core::option::Option::Some(::core::cmp::Ordering::Equal)
=>
match ::core::cmp::PartialOrd::partial_cmp(&self.b6,
&other.b6) {
::core::option::Option::Some(::core::cmp::Ordering::Equal)
=>
match ::core::cmp::PartialOrd::partial_cmp(&self.b7,
&other.b7) {
::core::option::Option::Some(::core::cmp::Ordering::Equal)
=>
::core::cmp::PartialOrd::partial_cmp(&self.b8, &other.b8),
cmp => cmp,
},
cmp => cmp,
},
cmp => cmp,
},
cmp => cmp,
},
cmp => cmp,
},
cmp => cmp,
},
cmp => cmp,
}
::core::option::Option::Some(self.cmp(other))
}
}
#[automatically_derived]
@@ -766,7 +716,7 @@ impl ::core::cmp::PartialOrd for Unsized {
#[inline]
fn partial_cmp(&self, other: &Unsized)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
::core::option::Option::Some(self.cmp(other))
}
}
#[automatically_derived]
@@ -1066,7 +1016,7 @@ impl ::core::cmp::PartialOrd for Enum0 {
#[inline]
fn partial_cmp(&self, other: &Enum0)
-> ::core::option::Option<::core::cmp::Ordering> {
match *self {}
::core::option::Option::Some(self.cmp(other))
}
}
#[automatically_derived]
@@ -1138,10 +1088,7 @@ impl ::core::cmp::PartialOrd for Enum1 {
#[inline]
fn partial_cmp(&self, other: &Enum1)
-> ::core::option::Option<::core::cmp::Ordering> {
match (self, other) {
(Enum1::Single { x: __self_0 }, Enum1::Single { x: __arg1_0 }) =>
::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
}
::core::option::Option::Some(self.cmp(other))
}
}
#[automatically_derived]
@@ -1202,7 +1149,7 @@ impl ::core::cmp::PartialOrd for Fieldless1 {
#[inline]
fn partial_cmp(&self, other: &Fieldless1)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ordering::Equal)
::core::option::Option::Some(self.cmp(other))
}
}
#[automatically_derived]
@@ -1279,9 +1226,7 @@ impl ::core::cmp::PartialOrd for Fieldless {
#[inline]
fn partial_cmp(&self, other: &Fieldless)
-> ::core::option::Option<::core::cmp::Ordering> {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
::core::cmp::PartialOrd::partial_cmp(&__self_discr, &__arg1_discr)
::core::option::Option::Some(self.cmp(other))
}
}
#[automatically_derived]
@@ -1393,23 +1338,7 @@ impl ::core::cmp::PartialOrd for Mixed {
#[inline]
fn partial_cmp(&self, other: &Mixed)
-> ::core::option::Option<::core::cmp::Ordering> {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
match (self, other) {
(Mixed::R(__self_0), Mixed::R(__arg1_0)) =>
::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
(Mixed::S { d1: __self_0, d2: __self_1 }, Mixed::S {
d1: __arg1_0, d2: __arg1_1 }) =>
match ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0)
{
::core::option::Option::Some(::core::cmp::Ordering::Equal)
=> ::core::cmp::PartialOrd::partial_cmp(__self_1, __arg1_1),
cmp => cmp,
},
_ =>
::core::cmp::PartialOrd::partial_cmp(&__self_discr,
&__arg1_discr),
}
::core::option::Option::Some(self.cmp(other))
}
}
#[automatically_derived]
@@ -1591,19 +1520,7 @@ impl ::core::cmp::PartialOrd for Fielded {
#[inline]
fn partial_cmp(&self, other: &Fielded)
-> ::core::option::Option<::core::cmp::Ordering> {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
match (self, other) {
(Fielded::X(__self_0), Fielded::X(__arg1_0)) =>
::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
(Fielded::Y(__self_0), Fielded::Y(__arg1_0)) =>
::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
(Fielded::Z(__self_0), Fielded::Z(__arg1_0)) =>
::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
_ =>
::core::cmp::PartialOrd::partial_cmp(&__self_discr,
&__arg1_discr),
}
::core::option::Option::Some(self.cmp(other))
}
}
#[automatically_derived]
@@ -18,8 +18,6 @@
//~| ERROR: cannot move out of a shared reference [E0507]
//~| ERROR: cannot move out of a shared reference [E0507]
//~| ERROR: cannot move out of a shared reference [E0507]
//~| ERROR: cannot move out of a shared reference [E0507]
//~| ERROR: cannot move out of a shared reference [E0507]
// Unrelated impl: additinal diagnostic should NOT be emitted
@@ -29,27 +29,6 @@ LL | struct StructA(String);
= note: `#[derive(PartialEq)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
|
LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
| ---------- in this derive macro expansion
LL | struct StructA(String);
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
|
= note: `#[derive(PartialOrd)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
|
LL | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
| ---------- in this derive macro expansion
LL | struct StructA(String);
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
|
= note: `#[derive(PartialOrd)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
|
@@ -92,7 +71,7 @@ LL | struct StructA(String);
= note: `#[derive(Clone)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
error[E0507]: cannot move out of `self` which is behind a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:28:9
--> $DIR/deriving-with-repr-packed-move-errors.rs:26:9
|
LL | self.0
| ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait
@@ -103,7 +82,7 @@ LL | self.0.clone()
| ++++++++
error[E0507]: cannot move out of `self` which is behind a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:38:20
--> $DIR/deriving-with-repr-packed-move-errors.rs:36:20
|
LL | let x = &{ self.0 };
| ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait
@@ -114,7 +93,7 @@ LL | let x = &{ self.0.clone() };
| ++++++++
error[E0507]: cannot move out of `self` which is behind a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:45:12
--> $DIR/deriving-with-repr-packed-move-errors.rs:43:12
|
LL | ({ self.0 }) == ({ other.0 })
| ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait
@@ -125,7 +104,7 @@ LL | ({ self.0.clone() }) == ({ other.0 })
| ++++++++
error[E0507]: cannot move out of `other` which is behind a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:45:28
--> $DIR/deriving-with-repr-packed-move-errors.rs:43:28
|
LL | ({ self.0 }) == ({ other.0 })
| ^^^^^^^ move occurs because `other.0` has type `String`, which does not implement the `Copy` trait
@@ -136,7 +115,7 @@ LL | ({ self.0 }) == ({ other.0.clone() })
| ++++++++
error[E0507]: cannot move out of `self` which is behind a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:53:36
--> $DIR/deriving-with-repr-packed-move-errors.rs:51:36
|
LL | PartialOrd::partial_cmp(&{ self.0 }, &{ other.0 })
| ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait
@@ -147,7 +126,7 @@ LL | PartialOrd::partial_cmp(&{ self.0.clone() }, &{ other.0 })
| ++++++++
error[E0507]: cannot move out of `other` which is behind a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:53:49
--> $DIR/deriving-with-repr-packed-move-errors.rs:51:49
|
LL | PartialOrd::partial_cmp(&{ self.0 }, &{ other.0 })
| ^^^^^^^ move occurs because `other.0` has type `String`, which does not implement the `Copy` trait
@@ -158,7 +137,7 @@ LL | PartialOrd::partial_cmp(&{ self.0 }, &{ other.0.clone() })
| ++++++++
error[E0507]: cannot move out of `self` which is behind a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:68:20
--> $DIR/deriving-with-repr-packed-move-errors.rs:66:20
|
LL | let x = &{ self.0 };
| ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait
@@ -169,7 +148,7 @@ LL | let x = &{ self.0.clone() };
| ++++++++
error[E0507]: cannot move out of `self` which is behind a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:75:12
--> $DIR/deriving-with-repr-packed-move-errors.rs:73:12
|
LL | ({ self.0 }) == ({ other.0 })
| ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait
@@ -180,7 +159,7 @@ LL | ({ self.0.clone() }) == ({ other.0 })
| ++++++++
error[E0507]: cannot move out of `other` which is behind a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:75:28
--> $DIR/deriving-with-repr-packed-move-errors.rs:73:28
|
LL | ({ self.0 }) == ({ other.0 })
| ^^^^^^^ move occurs because `other.0` has type `String`, which does not implement the `Copy` trait
@@ -191,7 +170,7 @@ LL | ({ self.0 }) == ({ other.0.clone() })
| ++++++++
error[E0507]: cannot move out of `self` which is behind a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:83:36
--> $DIR/deriving-with-repr-packed-move-errors.rs:81:36
|
LL | PartialOrd::partial_cmp(&{ self.0 }, &{ other.0 })
| ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait
@@ -202,7 +181,7 @@ LL | PartialOrd::partial_cmp(&{ self.0.clone() }, &{ other.0 })
| ++++++++
error[E0507]: cannot move out of `other` which is behind a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:83:49
--> $DIR/deriving-with-repr-packed-move-errors.rs:81:49
|
LL | PartialOrd::partial_cmp(&{ self.0 }, &{ other.0 })
| ^^^^^^^ move occurs because `other.0` has type `String`, which does not implement the `Copy` trait
@@ -213,7 +192,7 @@ LL | PartialOrd::partial_cmp(&{ self.0 }, &{ other.0.clone() })
| ++++++++
error[E0507]: cannot move out of `arg` which is behind a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:92:5
--> $DIR/deriving-with-repr-packed-move-errors.rs:90:5
|
LL | arg.0
| ^^^^^ move occurs because `arg.0` has type `String`, which does not implement the `Copy` trait
@@ -223,6 +202,6 @@ help: consider cloning the value if the performance cost is acceptable
LL | arg.0.clone()
| ++++++++
error: aborting due to 21 previous errors
error: aborting due to 19 previous errors
For more information about this error, try `rustc --explain E0507`.
+6 -12
View File
@@ -3,23 +3,17 @@
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
struct AllTheRanges {
a: Range<usize>,
//~^ ERROR can't compare
//~| ERROR Ord
//~^ ERROR Ord
b: RangeTo<usize>,
//~^ ERROR can't compare
//~| ERROR Ord
//~^ ERROR Ord
c: RangeFrom<usize>,
//~^ ERROR can't compare
//~| ERROR Ord
//~^ ERROR Ord
d: RangeFull,
//~^ ERROR can't compare
//~| ERROR Ord
//~^ ERROR Ord
e: RangeInclusive<usize>,
//~^ ERROR can't compare
//~| ERROR Ord
//~^ ERROR Ord
f: RangeToInclusive<usize>,
//~^ ERROR can't compare
//~| ERROR Ord
//~^ ERROR Ord
}
fn main() {}
+6 -72
View File
@@ -1,69 +1,3 @@
error[E0277]: can't compare `std::ops::Range<usize>` with `std::ops::Range<usize>`
--> $DIR/range_traits-1.rs:5:5
|
LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
| ---------- in this derive macro expansion
LL | struct AllTheRanges {
LL | a: Range<usize>,
| ^^^^^^^^^^^^^^^ no implementation for `std::ops::Range<usize> < std::ops::Range<usize>` and `std::ops::Range<usize> > std::ops::Range<usize>`
|
= help: the trait `PartialOrd` is not implemented for `std::ops::Range<usize>`
error[E0277]: can't compare `std::ops::RangeTo<usize>` with `std::ops::RangeTo<usize>`
--> $DIR/range_traits-1.rs:8:5
|
LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
| ---------- in this derive macro expansion
...
LL | b: RangeTo<usize>,
| ^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeTo<usize> < std::ops::RangeTo<usize>` and `std::ops::RangeTo<usize> > std::ops::RangeTo<usize>`
|
= help: the trait `PartialOrd` is not implemented for `std::ops::RangeTo<usize>`
error[E0277]: can't compare `std::ops::RangeFrom<usize>` with `std::ops::RangeFrom<usize>`
--> $DIR/range_traits-1.rs:11:5
|
LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
| ---------- in this derive macro expansion
...
LL | c: RangeFrom<usize>,
| ^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeFrom<usize> < std::ops::RangeFrom<usize>` and `std::ops::RangeFrom<usize> > std::ops::RangeFrom<usize>`
|
= help: the trait `PartialOrd` is not implemented for `std::ops::RangeFrom<usize>`
error[E0277]: can't compare `std::ops::RangeFull` with `std::ops::RangeFull`
--> $DIR/range_traits-1.rs:14:5
|
LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
| ---------- in this derive macro expansion
...
LL | d: RangeFull,
| ^^^^^^^^^^^^ no implementation for `std::ops::RangeFull < std::ops::RangeFull` and `std::ops::RangeFull > std::ops::RangeFull`
|
= help: the trait `PartialOrd` is not implemented for `std::ops::RangeFull`
error[E0277]: can't compare `std::ops::RangeInclusive<usize>` with `std::ops::RangeInclusive<usize>`
--> $DIR/range_traits-1.rs:17:5
|
LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
| ---------- in this derive macro expansion
...
LL | e: RangeInclusive<usize>,
| ^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeInclusive<usize> < std::ops::RangeInclusive<usize>` and `std::ops::RangeInclusive<usize> > std::ops::RangeInclusive<usize>`
|
= help: the trait `PartialOrd` is not implemented for `std::ops::RangeInclusive<usize>`
error[E0277]: can't compare `std::ops::RangeToInclusive<usize>` with `std::ops::RangeToInclusive<usize>`
--> $DIR/range_traits-1.rs:20:5
|
LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
| ---------- in this derive macro expansion
...
LL | f: RangeToInclusive<usize>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeToInclusive<usize> < std::ops::RangeToInclusive<usize>` and `std::ops::RangeToInclusive<usize> > std::ops::RangeToInclusive<usize>`
|
= help: the trait `PartialOrd` is not implemented for `std::ops::RangeToInclusive<usize>`
error[E0277]: the trait bound `std::ops::Range<usize>: Ord` is not satisfied
--> $DIR/range_traits-1.rs:5:5
|
@@ -74,7 +8,7 @@ LL | a: Range<usize>,
| ^^^^^^^^^^^^^^^ the trait `Ord` is not implemented for `std::ops::Range<usize>`
error[E0277]: the trait bound `std::ops::RangeTo<usize>: Ord` is not satisfied
--> $DIR/range_traits-1.rs:8:5
--> $DIR/range_traits-1.rs:7:5
|
LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
| --- in this derive macro expansion
@@ -83,7 +17,7 @@ LL | b: RangeTo<usize>,
| ^^^^^^^^^^^^^^^^^ the trait `Ord` is not implemented for `std::ops::RangeTo<usize>`
error[E0277]: the trait bound `std::ops::RangeFrom<usize>: Ord` is not satisfied
--> $DIR/range_traits-1.rs:11:5
--> $DIR/range_traits-1.rs:9:5
|
LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
| --- in this derive macro expansion
@@ -92,7 +26,7 @@ LL | c: RangeFrom<usize>,
| ^^^^^^^^^^^^^^^^^^^ the trait `Ord` is not implemented for `std::ops::RangeFrom<usize>`
error[E0277]: the trait bound `std::ops::RangeFull: Ord` is not satisfied
--> $DIR/range_traits-1.rs:14:5
--> $DIR/range_traits-1.rs:11:5
|
LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
| --- in this derive macro expansion
@@ -101,7 +35,7 @@ LL | d: RangeFull,
| ^^^^^^^^^^^^ the trait `Ord` is not implemented for `std::ops::RangeFull`
error[E0277]: the trait bound `std::ops::RangeInclusive<usize>: Ord` is not satisfied
--> $DIR/range_traits-1.rs:17:5
--> $DIR/range_traits-1.rs:13:5
|
LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
| --- in this derive macro expansion
@@ -110,7 +44,7 @@ LL | e: RangeInclusive<usize>,
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Ord` is not implemented for `std::ops::RangeInclusive<usize>`
error[E0277]: the trait bound `std::ops::RangeToInclusive<usize>: Ord` is not satisfied
--> $DIR/range_traits-1.rs:20:5
--> $DIR/range_traits-1.rs:15:5
|
LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
| --- in this derive macro expansion
@@ -118,6 +52,6 @@ LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
LL | f: RangeToInclusive<usize>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Ord` is not implemented for `std::ops::RangeToInclusive<usize>`
error: aborting due to 12 previous errors
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0277`.
+1 -1
View File
@@ -3,7 +3,6 @@ macro-stats MACRO EXPANSION STATS: macro_stats
macro-stats Macro Name Uses Lines Avg Lines Bytes Avg Bytes
macro-stats -----------------------------------------------------------------------------------
macro-stats #[derive(Clone)] 8 67 8.4 1_879 234.9
macro-stats #[derive(PartialOrd)] 1 17 17.0 675 675.0
macro-stats #[derive(Hash)] 2 17 8.5 565 282.5
macro-stats q! 1 26 26.0 519 519.0
macro-stats #[derive(Ord)] 1 15 15.0 503 503.0
@@ -11,6 +10,7 @@ macro-stats #[derive(Default)] 2 16 8.0
macro-stats #[derive(Eq)] 1 11 11.0 312 312.0
macro-stats #[derive(Debug)] 1 8 8.0 277 277.0
macro-stats #[derive(PartialEq)] 1 9 9.0 267 267.0
macro-stats #[derive(PartialOrd)] 1 8 8.0 235 235.0
macro-stats #[derive(Copy)] 1 2 2.0 61 61.0
macro-stats p! 1 3 3.0 32 32.0
macro-stats trait_impl_tys! 1 2 2.0 28 28.0
@@ -14,7 +14,6 @@
//~| ERROR: the trait bound `(i32) is 0..=999999999: Ord` is not satisfied
//~| ERROR: the trait bound `(i32) is 0..=999999999: Hash` is not satisfied
//~| ERROR: the trait bound `(i32) is 0..=999999999: Default` is not satisfied
//~| ERROR: can't compare `(i32) is 0..=999999999` with `_`
//~| ERROR: `==` cannot be applied
type NanoI32 = crate::pattern_type!(i32 is 0..=999_999_999);
@@ -37,17 +37,6 @@ LL | #[repr(transparent)]
LL | struct Nanoseconds(NanoI32);
| ^^^^^^^ the trait `Ord` is not implemented for `(i32) is 0..=999999999`
error[E0277]: can't compare `(i32) is 0..=999999999` with `_`
--> $DIR/derives_fail.rs:11:20
|
LL | #[derive(Clone, Copy, PartialEq, Eq, Debug, Ord, PartialOrd, Hash, Default)]
| ---------- in this derive macro expansion
LL | #[repr(transparent)]
LL | struct Nanoseconds(NanoI32);
| ^^^^^^^ no implementation for `(i32) is 0..=999999999 < _` and `(i32) is 0..=999999999 > _`
|
= help: the trait `PartialOrd<_>` is not implemented for `(i32) is 0..=999999999`
error[E0277]: the trait bound `(i32) is 0..=999999999: Hash` is not satisfied
--> $DIR/derives_fail.rs:11:20
|
@@ -66,7 +55,7 @@ LL | #[repr(transparent)]
LL | struct Nanoseconds(NanoI32);
| ^^^^^^^ the trait `Default` is not implemented for `(i32) is 0..=999999999`
error: aborting due to 7 previous errors
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0277, E0369.
For more information about an error, try `rustc --explain E0277`.