add a TrivialClone implementation when deriving both Clone and Copy
This commit is contained in:
parent
5fb5861765
commit
e4e765b1f6
17 changed files with 82 additions and 16 deletions
|
|
@ -1,4 +1,4 @@
|
|||
use rustc_ast::MetaItem;
|
||||
use rustc_ast::{MetaItem, Safety};
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_span::Span;
|
||||
|
||||
|
|
@ -24,6 +24,7 @@ pub(crate) fn expand_deriving_copy(
|
|||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
safety: Safety::Default,
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push);
|
||||
|
|
@ -48,6 +49,7 @@ pub(crate) fn expand_deriving_const_param_ty(
|
|||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
safety: Safety::Default,
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use rustc_ast::{self as ast, Generics, ItemKind, MetaItem, VariantData};
|
||||
use rustc_ast::{self as ast, Generics, ItemKind, MetaItem, Safety, VariantData};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_span::{Ident, Span, kw, sym};
|
||||
use rustc_span::{DUMMY_SP, Ident, Span, kw, sym};
|
||||
use thin_vec::{ThinVec, thin_vec};
|
||||
|
||||
use crate::deriving::generic::ty::*;
|
||||
|
|
@ -68,6 +68,26 @@ pub(crate) fn expand_deriving_clone(
|
|||
_ => cx.dcx().span_bug(span, "`#[derive(Clone)]` on trait item or impl item"),
|
||||
}
|
||||
|
||||
// If the clone method is just copying the value, also mark the type as
|
||||
// `TrivialClone` to allow some library optimizations.
|
||||
if is_simple {
|
||||
let trivial_def = TraitDef {
|
||||
span,
|
||||
path: path_std!(clone::TrivialClone),
|
||||
skip_path_as_bound: false,
|
||||
needs_copy_as_bound_if_packed: true,
|
||||
additional_bounds: bounds.clone(),
|
||||
supports_unions: true,
|
||||
methods: Vec::new(),
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
safety: Safety::Unsafe(DUMMY_SP),
|
||||
};
|
||||
|
||||
trivial_def.expand_ext(cx, mitem, item, push, true);
|
||||
}
|
||||
|
||||
let trait_def = TraitDef {
|
||||
span,
|
||||
path: path_std!(clone::Clone),
|
||||
|
|
@ -88,6 +108,7 @@ pub(crate) fn expand_deriving_clone(
|
|||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
safety: Safety::Default,
|
||||
};
|
||||
|
||||
trait_def.expand_ext(cx, mitem, item, push, is_simple)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use rustc_ast::{self as ast, MetaItem};
|
||||
use rustc_ast::{self as ast, MetaItem, Safety};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_span::{Span, sym};
|
||||
|
|
@ -44,6 +44,7 @@ pub(crate) fn expand_deriving_eq(
|
|||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
safety: Safety::Default,
|
||||
};
|
||||
trait_def.expand_ext(cx, mitem, item, push, true)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use rustc_ast::MetaItem;
|
||||
use rustc_ast::{MetaItem, Safety};
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_span::{Ident, Span, sym};
|
||||
use thin_vec::thin_vec;
|
||||
|
|
@ -35,6 +35,7 @@ pub(crate) fn expand_deriving_ord(
|
|||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
safety: Safety::Default,
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use rustc_ast::{BinOpKind, BorrowKind, Expr, ExprKind, MetaItem, Mutability};
|
||||
use rustc_ast::{BinOpKind, BorrowKind, Expr, ExprKind, MetaItem, Mutability, Safety};
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_span::{Span, sym};
|
||||
use thin_vec::thin_vec;
|
||||
|
|
@ -30,6 +30,7 @@ pub(crate) fn expand_deriving_partial_eq(
|
|||
associated_types: Vec::new(),
|
||||
is_const: false,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
safety: Safety::Default,
|
||||
};
|
||||
structural_trait_def.expand(cx, mitem, item, push);
|
||||
|
||||
|
|
@ -59,6 +60,7 @@ pub(crate) fn expand_deriving_partial_eq(
|
|||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
safety: Safety::Default,
|
||||
};
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use rustc_ast::{ExprKind, ItemKind, MetaItem, PatKind};
|
||||
use rustc_ast::{ExprKind, ItemKind, MetaItem, PatKind, Safety};
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_span::{Ident, Span, sym};
|
||||
use thin_vec::thin_vec;
|
||||
|
|
@ -65,6 +65,7 @@ pub(crate) fn expand_deriving_partial_ord(
|
|||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
safety: Safety::Default,
|
||||
};
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use rustc_ast::{self as ast, EnumDef, MetaItem};
|
||||
use rustc_ast::{self as ast, EnumDef, MetaItem, Safety};
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_session::config::FmtDebug;
|
||||
use rustc_span::{Ident, Span, Symbol, sym};
|
||||
|
|
@ -42,6 +42,7 @@ pub(crate) fn expand_deriving_debug(
|
|||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
safety: Safety::Default,
|
||||
};
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
use core::ops::ControlFlow;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::visit::visit_opt;
|
||||
use rustc_ast::{EnumDef, VariantData, attr};
|
||||
use rustc_ast::{self as ast, EnumDef, Safety, VariantData, attr};
|
||||
use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt};
|
||||
use rustc_span::{ErrorGuaranteed, Ident, Span, kw, sym};
|
||||
use smallvec::SmallVec;
|
||||
|
|
@ -52,6 +51,7 @@ pub(crate) fn expand_deriving_default(
|
|||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
safety: Safety::Default,
|
||||
};
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use rustc_ast as ast;
|
||||
use rustc_ast::{ItemKind, VariantData};
|
||||
use rustc_ast::{ItemKind, Safety, VariantData};
|
||||
use rustc_errors::MultiSpan;
|
||||
use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt};
|
||||
use rustc_span::{Ident, Span, kw, sym};
|
||||
|
|
@ -127,6 +127,7 @@ pub(crate) fn expand_deriving_from(
|
|||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
safety: Safety::Default,
|
||||
};
|
||||
|
||||
from_trait_def.expand(cx, mitem, annotatable, push);
|
||||
|
|
|
|||
|
|
@ -225,6 +225,9 @@ pub(crate) struct TraitDef<'a> {
|
|||
pub is_const: bool,
|
||||
|
||||
pub is_staged_api_crate: bool,
|
||||
|
||||
/// The safety of the `impl`.
|
||||
pub safety: Safety,
|
||||
}
|
||||
|
||||
pub(crate) struct MethodDef<'a> {
|
||||
|
|
@ -832,7 +835,7 @@ impl<'a> TraitDef<'a> {
|
|||
ast::ItemKind::Impl(ast::Impl {
|
||||
generics: trait_generics,
|
||||
of_trait: Some(Box::new(ast::TraitImplHeader {
|
||||
safety: ast::Safety::Default,
|
||||
safety: self.safety,
|
||||
polarity: ast::ImplPolarity::Positive,
|
||||
defaultness: ast::Defaultness::Final,
|
||||
constness: if self.is_const {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use rustc_ast::{MetaItem, Mutability};
|
||||
use rustc_ast::{MetaItem, Mutability, Safety};
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_span::{Span, sym};
|
||||
use thin_vec::thin_vec;
|
||||
|
|
@ -42,6 +42,7 @@ pub(crate) fn expand_deriving_hash(
|
|||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
is_staged_api_crate: cx.ecfg.features.staged_api(),
|
||||
safety: Safety::Default,
|
||||
};
|
||||
|
||||
hash_trait_def.expand(cx, mitem, item, push);
|
||||
|
|
|
|||
|
|
@ -372,6 +372,7 @@ symbols! {
|
|||
ToString,
|
||||
TokenStream,
|
||||
Trait,
|
||||
TrivialClone,
|
||||
Try,
|
||||
TryCaptureGeneric,
|
||||
TryCapturePrintable,
|
||||
|
|
|
|||
|
|
@ -280,7 +280,7 @@ pub const unsafe trait TrivialClone: [const] Clone {}
|
|||
/// Derive macro generating an impl of the trait `Clone`.
|
||||
#[rustc_builtin_macro]
|
||||
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
|
||||
#[allow_internal_unstable(core_intrinsics, derive_clone_copy)]
|
||||
#[allow_internal_unstable(core_intrinsics, derive_clone_copy, trivial_clone)]
|
||||
pub macro Clone($item:item) {
|
||||
/* compiler built-in */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#[derive(Copy, Clone)]
|
||||
//~^ ERROR conflicting implementations of trait `Clone` for type `E`
|
||||
//~| ERROR conflicting implementations of trait `Copy` for type `E`
|
||||
//~| ERROR conflicting implementations of trait `TrivialClone` for type `E`
|
||||
enum E {}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,16 @@ LL | #[derive(Copy, Clone)]
|
|||
LL | #[derive(Copy, Clone)]
|
||||
| ^^^^ conflicting implementation for `E`
|
||||
|
||||
error[E0119]: conflicting implementations of trait `TrivialClone` for type `E`
|
||||
--> $DIR/duplicate-derive-copy-clone-diagnostics.rs:6:16
|
||||
|
|
||||
LL | #[derive(Copy, Clone)]
|
||||
| ----- first implementation here
|
||||
LL | #[derive(Copy, Clone)]
|
||||
| ^^^^^ conflicting implementation for `E`
|
||||
|
|
||||
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Clone` for type `E`
|
||||
--> $DIR/duplicate-derive-copy-clone-diagnostics.rs:6:16
|
||||
|
|
||||
|
|
@ -14,6 +24,6 @@ LL | #[derive(Copy, Clone)]
|
|||
LL | #[derive(Copy, Clone)]
|
||||
| ^^^^^ conflicting implementation for `E`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ use std::from::From;
|
|||
// Empty struct.
|
||||
struct Empty;
|
||||
#[automatically_derived]
|
||||
unsafe impl ::core::clone::TrivialClone for Empty { }
|
||||
#[automatically_derived]
|
||||
impl ::core::clone::Clone for Empty {
|
||||
#[inline]
|
||||
fn clone(&self) -> Empty { *self }
|
||||
|
|
@ -88,6 +90,8 @@ struct Point {
|
|||
y: u32,
|
||||
}
|
||||
#[automatically_derived]
|
||||
unsafe impl ::core::clone::TrivialClone for Point { }
|
||||
#[automatically_derived]
|
||||
impl ::core::clone::Clone for Point {
|
||||
#[inline]
|
||||
fn clone(&self) -> Point {
|
||||
|
|
@ -173,6 +177,8 @@ struct PackedPoint {
|
|||
y: u32,
|
||||
}
|
||||
#[automatically_derived]
|
||||
unsafe impl ::core::clone::TrivialClone for PackedPoint { }
|
||||
#[automatically_derived]
|
||||
impl ::core::clone::Clone for PackedPoint {
|
||||
#[inline]
|
||||
fn clone(&self) -> PackedPoint {
|
||||
|
|
@ -254,6 +260,8 @@ impl ::core::cmp::Ord for PackedPoint {
|
|||
|
||||
struct TupleSingleField(u32);
|
||||
#[automatically_derived]
|
||||
unsafe impl ::core::clone::TrivialClone for TupleSingleField { }
|
||||
#[automatically_derived]
|
||||
impl ::core::clone::Clone for TupleSingleField {
|
||||
#[inline]
|
||||
fn clone(&self) -> TupleSingleField {
|
||||
|
|
@ -326,6 +334,8 @@ struct SingleField {
|
|||
foo: bool,
|
||||
}
|
||||
#[automatically_derived]
|
||||
unsafe impl ::core::clone::TrivialClone for SingleField { }
|
||||
#[automatically_derived]
|
||||
impl ::core::clone::Clone for SingleField {
|
||||
#[inline]
|
||||
fn clone(&self) -> SingleField {
|
||||
|
|
@ -407,6 +417,8 @@ struct Big {
|
|||
b8: u32,
|
||||
}
|
||||
#[automatically_derived]
|
||||
unsafe impl ::core::clone::TrivialClone for Big { }
|
||||
#[automatically_derived]
|
||||
impl ::core::clone::Clone for Big {
|
||||
#[inline]
|
||||
fn clone(&self) -> Big {
|
||||
|
|
@ -1007,6 +1019,8 @@ impl<T: ::core::cmp::Ord + ::core::marker::Copy + Trait, U: ::core::cmp::Ord +
|
|||
// An empty enum.
|
||||
enum Enum0 {}
|
||||
#[automatically_derived]
|
||||
unsafe impl ::core::clone::TrivialClone for Enum0 { }
|
||||
#[automatically_derived]
|
||||
impl ::core::clone::Clone for Enum0 {
|
||||
#[inline]
|
||||
fn clone(&self) -> Enum0 { *self }
|
||||
|
|
@ -1202,6 +1216,8 @@ enum Fieldless {
|
|||
C,
|
||||
}
|
||||
#[automatically_derived]
|
||||
unsafe impl ::core::clone::TrivialClone for Fieldless { }
|
||||
#[automatically_derived]
|
||||
impl ::core::clone::Clone for Fieldless {
|
||||
#[inline]
|
||||
fn clone(&self) -> Fieldless { *self }
|
||||
|
|
@ -1284,6 +1300,8 @@ enum Mixed {
|
|||
},
|
||||
}
|
||||
#[automatically_derived]
|
||||
unsafe impl ::core::clone::TrivialClone for Mixed { }
|
||||
#[automatically_derived]
|
||||
impl ::core::clone::Clone for Mixed {
|
||||
#[inline]
|
||||
fn clone(&self) -> Mixed {
|
||||
|
|
@ -1752,6 +1770,8 @@ pub union Union {
|
|||
pub i: i32,
|
||||
}
|
||||
#[automatically_derived]
|
||||
unsafe impl ::core::clone::TrivialClone for Union { }
|
||||
#[automatically_derived]
|
||||
impl ::core::clone::Clone for Union {
|
||||
#[inline]
|
||||
fn clone(&self) -> Union {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ macro-stats ====================================================================
|
|||
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 64 8.0 1_788 223.5
|
||||
macro-stats #[derive(Clone)] 8 66 8.2 1_864 233.0
|
||||
macro-stats #[derive(PartialOrd)] 1 17 17.0 675 675.0
|
||||
macro-stats #[derive(Hash)] 2 17 8.5 577 288.5
|
||||
macro-stats q! 1 26 26.0 519 519.0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue