Skip to content
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