mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-29 20:46:07 +03:00
Implement fast path for derive(PartialOrd)
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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(
|
||||
|
||||
+3
-38
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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`.
|
||||
|
||||
Reference in New Issue
Block a user