Skip to content

Make #[derive(Copy, Eq, Ord)] imply #[derive(Clone, PartialEq, PartialOrd)] #23905

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
1 change: 1 addition & 0 deletions src/libcollections/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,7 @@ impl<'a, 'b> Pattern<'a> for &'b String {
}
}

#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for String {
#[inline]
Expand Down
2 changes: 2 additions & 0 deletions src/libcore/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

use cell::{Cell, RefCell, Ref, RefMut, BorrowState};
use char::CharExt;
#[cfg(stage0)]
use clone::Clone;
use iter::Iterator;
use marker::{Copy, PhantomData, Sized};
Expand Down Expand Up @@ -141,6 +142,7 @@ pub struct ArgumentV1<'a> {
formatter: fn(&Void, &mut Formatter) -> Result,
}

#[cfg(stage0)]
impl<'a> Clone for ArgumentV1<'a> {
fn clone(&self) -> ArgumentV1<'a> {
*self
Expand Down
3 changes: 3 additions & 0 deletions src/liblibc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2091,6 +2091,7 @@ pub mod types {
pub __ss_align: i64,
pub __ss_pad2: [u8; 112],
}
#[cfg(stage0)]
impl ::core::clone::Clone for sockaddr_storage {
fn clone(&self) -> sockaddr_storage { *self }
}
Expand Down Expand Up @@ -2154,6 +2155,7 @@ pub mod types {
pub sun_family: sa_family_t,
pub sun_path: [c_char; 104]
}
#[cfg(stage0)]
impl ::core::clone::Clone for sockaddr_un {
fn clone(&self) -> sockaddr_un { *self }
}
Expand Down Expand Up @@ -2369,6 +2371,7 @@ pub mod types {
pub __sig: c_long,
pub __opaque: [c_char; 56]
}
#[cfg(stage0)]
impl ::core::clone::Clone for pthread_attr_t {
fn clone(&self) -> pthread_attr_t { *self }
}
Expand Down
2 changes: 2 additions & 0 deletions src/librand/isaac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ impl IsaacRng {
}

// Cannot be derived because [u32; 256] does not implement Clone
#[cfg(stage0)]
impl Clone for IsaacRng {
fn clone(&self) -> IsaacRng {
*self
Expand Down Expand Up @@ -432,6 +433,7 @@ impl Isaac64Rng {
}

// Cannot be derived because [u32; 256] does not implement Clone
#[cfg(stage0)]
impl Clone for Isaac64Rng {
fn clone(&self) -> Isaac64Rng {
*self
Expand Down
1 change: 1 addition & 0 deletions src/librustc/middle/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ impl LiveNode {
fn get(&self) -> usize { let LiveNode(v) = *self; v }
}

#[cfg(stage0)]
impl Clone for LiveNode {
fn clone(&self) -> LiveNode {
LiveNode(self.get())
Expand Down
4 changes: 3 additions & 1 deletion src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1708,7 +1708,7 @@ pub enum UnconstrainedNumeric {
}


#[derive(Clone, RustcEncodable, RustcDecodable, Eq, Hash, Debug, Copy)]
#[derive(Clone, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum InferRegion {
ReVar(RegionVid),
ReSkolemized(u32, BoundRegion)
Expand All @@ -1731,6 +1731,8 @@ impl cmp::PartialEq for InferRegion {
}
}

impl cmp::Eq for InferRegion {}

impl fmt::Debug for TyVid {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result{
write!(f, "_#{}t", self.index)
Expand Down
5 changes: 4 additions & 1 deletion src/librustc_borrowck/borrowck/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ impl<'tcx> Loan<'tcx> {
}
}

#[derive(Eq, Hash, Debug)]
#[derive(Hash, Debug)]
pub struct LoanPath<'tcx> {
kind: LoanPathKind<'tcx>,
ty: ty::Ty<'tcx>,
Expand All @@ -293,6 +293,9 @@ impl<'tcx> PartialEq for LoanPath<'tcx> {
}
}

impl<'tcx> Eq for LoanPath<'tcx> {}


#[derive(PartialEq, Eq, Hash, Debug)]
pub enum LoanPathKind<'tcx> {
LpVar(ast::NodeId), // `x` in README.md
Expand Down
1 change: 1 addition & 0 deletions src/librustc_borrowck/borrowck/move_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ impl MovePathIndex {
}
}

#[cfg(stage0)]
impl Clone for MovePathIndex {
fn clone(&self) -> MovePathIndex {
MovePathIndex(self.get())
Expand Down
3 changes: 3 additions & 0 deletions src/libstd/net/addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,13 @@ impl fmt::Debug for SocketAddrV6 {
}
}

#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl Clone for SocketAddrV4 {
fn clone(&self) -> SocketAddrV4 { *self }
}

#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl Clone for SocketAddrV6 {
fn clone(&self) -> SocketAddrV6 { *self }
Expand Down
2 changes: 2 additions & 0 deletions src/libstd/net/ip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ impl fmt::Debug for Ipv4Addr {
}
}

#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl Clone for Ipv4Addr {
fn clone(&self) -> Ipv4Addr { *self }
Expand Down Expand Up @@ -417,6 +418,7 @@ impl fmt::Debug for Ipv6Addr {
}
}

#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl Clone for Ipv6Addr {
fn clone(&self) -> Ipv6Addr { *self }
Expand Down
5 changes: 4 additions & 1 deletion src/libstd/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ enum State {
///
/// Does not occur on Unix.
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Copy, Clone, Eq, Hash, Debug)]
#[derive(Copy, Clone, Hash, Debug)]
pub struct PrefixComponent<'a> {
/// The prefix as an unparsed `OsStr` slice.
raw: &'a OsStr,
Expand All @@ -472,6 +472,9 @@ impl<'a> PrefixComponent<'a> {
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> cmp::Eq for PrefixComponent<'a> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> cmp::PartialEq for PrefixComponent<'a> {
fn eq(&self, other: &PrefixComponent<'a>) -> bool {
Expand Down
8 changes: 6 additions & 2 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ use serialize::{Encodable, Decodable, Encoder, Decoder};
/// table) and a SyntaxContext to track renaming and
/// macro expansion per Flatt et al., "Macros
/// That Work Together"
#[derive(Clone, Copy, Hash, PartialOrd, Eq, Ord)]
#[derive(Clone, Copy, Hash, PartialOrd, Ord)]
pub struct Ident {
pub name: Name,
pub ctxt: SyntaxContext
Expand Down Expand Up @@ -149,6 +149,8 @@ impl PartialEq for Ident {
}
}

impl Eq for Ident {}

/// A SyntaxContext represents a chain of macro-expandings
/// and renamings. Each macro expansion corresponds to
/// a fresh u32
Expand Down Expand Up @@ -502,7 +504,7 @@ pub struct Crate {

pub type MetaItem = Spanned<MetaItem_>;

#[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
#[derive(Clone, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum MetaItem_ {
MetaWord(InternedString),
MetaList(InternedString, Vec<P<MetaItem>>),
Expand Down Expand Up @@ -534,6 +536,8 @@ impl PartialEq for MetaItem_ {
}
}

impl Eq for MetaItem_ {}

#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Block {
/// Statements in a block
Expand Down
1 change: 1 addition & 0 deletions src/libsyntax/ast_map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ enum MapEntry<'ast> {
RootInlinedParent(&'ast InlinedParent)
}

#[cfg(stage0)]
impl<'ast> Clone for MapEntry<'ast> {
fn clone(&self) -> MapEntry<'ast> {
*self
Expand Down
139 changes: 118 additions & 21 deletions src/libsyntax/ext/deriving/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,45 +8,142 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use ast::{MetaItem, Item};
use codemap::Span;
use abi;
use ast::{self, MetaItem, Item};
use codemap::{Span, respan};
use ext::base::ExtCtxt;
use ext::build::AstBuilder;
use ext::deriving::generic::*;
use ext::deriving::generic::ty::*;
use owned_slice::OwnedSlice;
use parse::token::{InternedString, special_idents};
use ptr::P;

pub fn expand_deriving_unsafe_bound<F>(cx: &mut ExtCtxt,
span: Span,
_: &MetaItem,
_: &Item,
_: F) where
F: FnOnce(P<Item>),
use super::clone;

pub fn expand_deriving_unsafe_bound(cx: &mut ExtCtxt,
span: Span,
_: &MetaItem,
_: &Item,
_: &mut FnMut(P<Item>))
{
cx.span_err(span, "this unsafe trait should be implemented explicitly");
}

pub fn expand_deriving_copy<F>(cx: &mut ExtCtxt,
span: Span,
mitem: &MetaItem,
item: &Item,
push: F) where
F: FnOnce(P<Item>),
pub fn expand_deriving_copy(cx: &mut ExtCtxt,
span: Span,
mitem: &MetaItem,
item: &Item,
push: &mut FnMut(P<Item>))
{
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
path: path_std!(cx, core::marker::Copy),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
methods: Vec::new(),
associated_types: Vec::new(),
};

trait_def.expand(cx, mitem, item, push);

expand_deriving_clone_when_copy(cx, span, mitem, item, push)
}

fn expand_deriving_clone_when_copy(cx: &mut ExtCtxt,
span: Span,
mitem: &MetaItem,
item: &Item,
push: &mut FnMut(P<Item>))
{
let path = Path::new(vec![
if cx.use_std { "std" } else { "core" },
"marker",
"Copy",
]);
// For generic types we need to destructure our value in order to recursively call clone.
// However, as an optimization for non-generic types, we can just generate:
//
// impl<...> Clone for $ty {
// fn clone(&self) -> Self { *self }
// }
//
// But the generic deriving helpers do not support generating such a simple method. So we'll
// build this method by hand. However, we want to take advantage of generic deriving generating
// the `Generics` for us. So we'll generate an empty impl, then later on add our method. It's
// not pretty, but it works until we get a more general purpose ast builder.
match item.node {
ast::ItemStruct(_, ref generics) | ast::ItemEnum(_, ref generics) => {
if generics.is_type_parameterized() {
clone::expand_deriving_clone(cx, span, mitem, item, push);
return;
}
}
_ => {
cx.span_err(mitem.span, "`derive` may only be applied to structs and enums");
return;
}
}

let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
path: path,
path: path_std!(cx, core::clone::Clone),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
methods: Vec::new(),
associated_types: Vec::new(),
};

trait_def.expand(cx, mitem, item, push)
// We want to use the `cx` to build our ast, but it's passed by `&mut` to the expand method. So
// we'll extract out the generated item by way of an option.
let mut expanded_item = None;

trait_def.expand(cx, mitem, item, &mut |item: P<ast::Item>| {
expanded_item = Some(item);
});

let expanded_item = expanded_item.unwrap().map(|mut item| {
match item.node {
ast::ItemImpl(_, _, _, _, ref ty, ref mut impl_items) => {
let self_arg = ast::Arg::new_self(span, ast::MutImmutable, special_idents::self_);
let decl = cx.fn_decl(vec![self_arg], ty.clone());

let sig = ast::MethodSig {
unsafety: ast::Unsafety::Normal,
abi: abi::Rust,
decl: decl.clone(),
generics: ast::Generics {
lifetimes: Vec::new(),
ty_params: OwnedSlice::empty(),
where_clause: ast::WhereClause {
id: ast::DUMMY_NODE_ID,
predicates: Vec::new(),
}
},
explicit_self: respan(
span,
ast::SelfRegion(None, ast::MutImmutable, cx.ident_of("self")),
),
};

let block = cx.block_expr(cx.expr_deref(span, cx.expr_self(span)));

let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline));

impl_items.push(P(ast::ImplItem {
id: ast::DUMMY_NODE_ID,
ident: cx.ident_of("clone"),
vis: ast::Visibility::Inherited,
attrs: attrs,
node: ast::ImplItem_::MethodImplItem(sig, block),
span: span,
}));
}
_ => {
cx.span_bug(span, "we should have gotten an impl")
}
};

item
});

push(expanded_item)
}
11 changes: 5 additions & 6 deletions src/libsyntax/ext/deriving/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,11 @@ use ext::deriving::generic::ty::*;
use parse::token::InternedString;
use ptr::P;

pub fn expand_deriving_clone<F>(cx: &mut ExtCtxt,
span: Span,
mitem: &MetaItem,
item: &Item,
push: F) where
F: FnOnce(P<Item>),
pub fn expand_deriving_clone(cx: &mut ExtCtxt,
span: Span,
mitem: &MetaItem,
item: &Item,
push: &mut FnMut(P<Item>))
{
let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline));
Expand Down
Loading