From 096a28607fb80c91e6e2ca64d9ef44c4e550e96c Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 5 Dec 2014 17:01:33 -0800 Subject: [PATCH 1/3] librustc: Make `Copy` opt-in. This change makes the compiler no longer infer whether types (structures and enumerations) implement the `Copy` trait (and thus are implicitly copyable). Rather, you must implement `Copy` yourself via `impl Copy for MyType {}`. A new warning has been added, `missing_copy_implementations`, to warn you if a non-generic public type has been added that could have implemented `Copy` but didn't. For convenience, you may *temporarily* opt out of this behavior by using `#![feature(opt_out_copy)]`. Note though that this feature gate will never be accepted and will be removed by the time that 1.0 is released, so you should transition your code away from using it. This breaks code like: #[deriving(Show)] struct Point2D { x: int, y: int, } fn main() { let mypoint = Point2D { x: 1, y: 1, }; let otherpoint = mypoint; println!("{}{}", mypoint, otherpoint); } Change this code to: #[deriving(Show)] struct Point2D { x: int, y: int, } impl Copy for Point2D {} fn main() { let mypoint = Point2D { x: 1, y: 1, }; let otherpoint = mypoint; println!("{}{}", mypoint, otherpoint); } This is the backwards-incompatible part of #13231. Part of RFC #3. [breaking-change] --- src/compiletest/common.rs | 2 + src/doc/guide-unsafe.md | 3 + src/doc/reference.md | 4 + src/libarena/lib.rs | 2 +- src/libcollections/binary_heap.rs | 2 + src/libcollections/dlist.rs | 9 +- src/libcollections/enum_set.rs | 7 + src/libcollections/hash/sip.rs | 3 + src/libcollections/slice.rs | 16 +- src/libcollections/str.rs | 34 ++- src/libcore/atomic.rs | 3 + src/libcore/char.rs | 1 + src/libcore/cmp.rs | 7 +- src/libcore/fmt/mod.rs | 4 + src/libcore/fmt/num.rs | 5 + src/libcore/fmt/rt.rs | 13 + src/libcore/intrinsics.rs | 6 + src/libcore/iter.rs | 11 +- src/libcore/kinds.rs | 17 ++ src/libcore/lib.rs | 2 +- src/libcore/num/mod.rs | 2 + src/libcore/ops.rs | 32 +++ src/libcore/option.rs | 7 +- src/libcore/ptr.rs | 1 + src/libcore/raw.rs | 9 + src/libcore/result.rs | 5 + src/libcore/simd.rs | 23 ++ src/libcore/slice.rs | 6 + src/libcore/str.rs | 9 +- src/libfmt_macros/lib.rs | 14 + src/libgetopts/lib.rs | 26 +- src/liblibc/lib.rs | 248 ++++++++++-------- src/liblog/lib.rs | 4 + src/librand/chacha.rs | 2 + src/librand/distributions/exponential.rs | 5 + src/librand/distributions/normal.rs | 7 + src/librand/isaac.rs | 5 + src/librand/lib.rs | 12 + src/librand/reseeding.rs | 2 + src/librbml/lib.rs | 6 + src/libregex/parse.rs | 2 + src/libregex/re.rs | 8 +- src/libregex/vm.rs | 4 + src/librustc/lint/builtin.rs | 102 ++++++- src/librustc/lint/context.rs | 1 + src/librustc/lint/mod.rs | 8 + src/librustc/metadata/common.rs | 2 + src/librustc/metadata/creader.rs | 6 +- src/librustc/metadata/csearch.rs | 7 +- src/librustc/metadata/cstore.rs | 17 +- src/librustc/metadata/decoder.rs | 6 +- src/librustc/metadata/filesearch.rs | 7 +- src/librustc/metadata/tydecode.rs | 2 + src/librustc/middle/borrowck/check_loans.rs | 14 +- .../middle/borrowck/gather_loans/mod.rs | 12 +- src/librustc/middle/borrowck/graphviz.rs | 2 + src/librustc/middle/borrowck/mod.rs | 37 ++- src/librustc/middle/borrowck/move_data.rs | 16 ++ src/librustc/middle/cfg/construct.rs | 2 + src/librustc/middle/cfg/mod.rs | 2 + src/librustc/middle/check_loop.rs | 4 + src/librustc/middle/check_match.rs | 26 +- src/librustc/middle/check_rvalues.rs | 6 +- src/librustc/middle/check_static.rs | 10 +- src/librustc/middle/const_eval.rs | 2 + src/librustc/middle/dataflow.rs | 7 +- src/librustc/middle/def.rs | 4 + src/librustc/middle/effect.rs | 2 + src/librustc/middle/expr_use_visitor.rs | 69 ++++- src/librustc/middle/fast_reject.rs | 2 + src/librustc/middle/graph.rs | 6 + src/librustc/middle/infer/mod.rs | 6 + .../middle/infer/region_inference/mod.rs | 16 ++ src/librustc/middle/infer/type_variable.rs | 2 + src/librustc/middle/infer/unify.rs | 2 + src/librustc/middle/lang_items.rs | 2 + src/librustc/middle/liveness.rs | 15 ++ src/librustc/middle/mem_categorization.rs | 22 ++ src/librustc/middle/region.rs | 4 + src/librustc/middle/resolve.rs | 40 +++ src/librustc/middle/resolve_lifetime.rs | 2 + src/librustc/middle/subst.rs | 2 + src/librustc/middle/traits/mod.rs | 8 +- src/librustc/middle/traits/select.rs | 29 +- src/librustc/middle/ty.rs | 229 +++++++++++++--- src/librustc/session/config.rs | 12 +- src/librustc/util/common.rs | 2 + src/librustc/util/nodemap.rs | 3 + src/librustc_driver/pretty.rs | 4 + src/librustc_llvm/diagnostic.rs | 6 + src/librustc_llvm/lib.rs | 65 +++++ src/librustc_trans/back/write.rs | 11 + src/librustc_trans/save/mod.rs | 2 +- src/librustc_trans/save/recorder.rs | 7 +- src/librustc_trans/save/span_utils.rs | 1 + src/librustc_trans/trans/_match.rs | 27 +- src/librustc_trans/trans/adt.rs | 5 +- src/librustc_trans/trans/base.rs | 24 +- src/librustc_trans/trans/basic_block.rs | 2 + src/librustc_trans/trans/cabi.rs | 4 + src/librustc_trans/trans/cabi_x86_64.rs | 2 + src/librustc_trans/trans/callee.rs | 4 + src/librustc_trans/trans/cleanup.rs | 18 ++ src/librustc_trans/trans/closure.rs | 2 + src/librustc_trans/trans/common.rs | 9 +- src/librustc_trans/trans/datum.rs | 24 +- src/librustc_trans/trans/debuginfo.rs | 6 + src/librustc_trans/trans/expr.rs | 4 + src/librustc_trans/trans/mod.rs | 2 + src/librustc_trans/trans/tvec.rs | 4 +- src/librustc_trans/trans/type_.rs | 2 + src/librustc_trans/trans/type_of.rs | 5 +- src/librustc_trans/trans/value.rs | 10 +- src/librustc_typeck/check/method/mod.rs | 2 + src/librustc_typeck/check/mod.rs | 8 + src/librustc_typeck/check/wf.rs | 5 + src/librustc_typeck/check/writeback.rs | 2 + src/librustc_typeck/coherence/mod.rs | 80 +++++- src/librustc_typeck/collect.rs | 2 + src/librustc_typeck/rscope.rs | 3 + src/librustc_typeck/variance.rs | 10 +- src/librustdoc/clean/mod.rs | 6 + src/librustdoc/doctree.rs | 2 + src/librustdoc/html/format.rs | 5 + src/librustdoc/html/item_type.rs | 2 + src/librustdoc/html/render.rs | 8 +- src/librustdoc/stability_summary.rs | 2 + src/librustrt/bookkeeping.rs | 1 + src/librustrt/c_str.rs | 1 + src/librustrt/mutex.rs | 12 + src/librustrt/unwind.rs | 1 + src/librustrt/util.rs | 3 + src/libserialize/base64.rs | 6 + src/libserialize/hex.rs | 2 + src/libserialize/json.rs | 4 + src/libstd/ascii.rs | 3 + src/libstd/bitflags.rs | 9 + src/libstd/collections/hash/table.rs | 6 +- src/libstd/comm/mod.rs | 2 + src/libstd/dynamic_lib.rs | 8 +- src/libstd/io/mod.rs | 17 ++ src/libstd/io/net/addrinfo.rs | 11 + src/libstd/io/net/ip.rs | 5 + src/libstd/io/process.rs | 4 + src/libstd/io/util.rs | 6 + src/libstd/num/strconv.rs | 51 ++-- src/libstd/os.rs | 12 + src/libstd/path/windows.rs | 3 + src/libstd/rand/mod.rs | 7 +- src/libstd/time/duration.rs | 3 + src/libsyntax/abi.rs | 22 +- src/libsyntax/ast.rs | 65 ++++- src/libsyntax/ast_map/blocks.rs | 4 + src/libsyntax/ast_map/mod.rs | 6 + src/libsyntax/ast_util.rs | 2 + src/libsyntax/attr.rs | 8 + src/libsyntax/codemap.rs | 14 + src/libsyntax/diagnostic.rs | 10 + src/libsyntax/ext/base.rs | 10 +- src/libsyntax/ext/deriving/cmp/ord.rs | 2 + src/libsyntax/ext/mtwt.rs | 2 + src/libsyntax/feature_gate.rs | 2 + src/libsyntax/parse/lexer/comments.rs | 2 + src/libsyntax/parse/obsolete.rs | 2 + src/libsyntax/parse/parser.rs | 4 + src/libsyntax/parse/token.rs | 12 + src/libsyntax/print/pp.rs | 10 + src/libsyntax/print/pprust.rs | 4 + src/libsyntax/visit.rs | 2 + src/libterm/lib.rs | 3 + src/libterm/terminfo/parm.rs | 8 + src/libtest/lib.rs | 19 +- src/libtime/lib.rs | 12 +- src/libunicode/tables.rs | 3 + src/test/auxiliary/issue-14422.rs | 2 + src/test/auxiliary/issue13213aux.rs | 4 + src/test/auxiliary/lang-item-public.rs | 5 + src/test/auxiliary/method_self_arg1.rs | 2 + src/test/auxiliary/method_self_arg2.rs | 2 + src/test/auxiliary/xcrate_unit_struct.rs | 11 + src/test/bench/noise.rs | 2 + src/test/bench/shootout-chameneos-redux.rs | 11 +- src/test/bench/shootout-fannkuch-redux.rs | 4 + src/test/bench/shootout-fasta-redux.rs | 2 + src/test/bench/shootout-k-nucleotide.rs | 2 + src/test/bench/shootout-nbody.rs | 2 + .../borrowck-borrow-from-owned-ptr.rs | 4 + .../borrowck-borrow-from-stack-variable.rs | 4 + ...borrowck-loan-local-as-both-mut-and-imm.rs | 35 --- .../compile-fail/borrowck-use-mut-borrow.rs | 3 + src/test/compile-fail/dst-index.rs | 7 +- src/test/compile-fail/dst-rvalue.rs | 2 + src/test/compile-fail/issue-17651.rs | 3 +- src/test/compile-fail/kindck-copy.rs | 3 + src/test/compile-fail/lint-dead-code-1.rs | 1 + src/test/compile-fail/lint-missing-doc.rs | 1 + src/test/compile-fail/opt-in-copy.rs | 33 +++ .../stage0-clone-contravariant-lifetime.rs | 43 --- src/test/compile-fail/stage0-cmp.rs | 39 --- src/test/debuginfo/c-style-enum.rs | 3 + .../generic-method-on-generic-struct.rs | 3 + src/test/debuginfo/method-on-enum.rs | 3 + .../debuginfo/method-on-generic-struct.rs | 3 + src/test/debuginfo/method-on-struct.rs | 3 + src/test/debuginfo/method-on-trait.rs | 3 + src/test/debuginfo/method-on-tuple-struct.rs | 3 + src/test/debuginfo/self-in-default-method.rs | 3 + .../self-in-generic-default-method.rs | 3 + src/test/pretty/block-disambig.rs | 2 + .../extern-fn-with-packed-struct/test.rs | 2 + src/test/run-make/target-specs/foo.rs | 3 + src/test/run-pass/borrowck-univariant-enum.rs | 2 + .../builtin-superkinds-in-metadata.rs | 8 +- src/test/run-pass/cell-does-not-clone.rs | 2 + .../class-impl-very-parameterized-trait.rs | 2 + src/test/run-pass/coherence-impl-in-fn.rs | 1 + src/test/run-pass/coherence-where-clause.rs | 2 + .../run-pass/const-nullary-univariant-enum.rs | 2 + src/test/run-pass/dst-struct-sole.rs | 2 + src/test/run-pass/dst-struct.rs | 2 + src/test/run-pass/dst-trait.rs | 4 + src/test/run-pass/empty-tag.rs | 2 + src/test/run-pass/enum-discrim-width-stuff.rs | 1 + src/test/run-pass/explicit-self-generic.rs | 4 + src/test/run-pass/export-unexported-dep.rs | 2 + src/test/run-pass/expr-copy.rs | 2 + src/test/run-pass/expr-if-struct.rs | 4 + src/test/run-pass/expr-match-struct.rs | 4 + src/test/run-pass/exterior.rs | 2 + src/test/run-pass/extern-pass-TwoU16s.rs | 2 + src/test/run-pass/extern-pass-TwoU32s.rs | 2 + src/test/run-pass/extern-pass-TwoU64s.rs | 2 + src/test/run-pass/extern-pass-TwoU8s.rs | 2 + src/test/run-pass/foreign-fn-with-byval.rs | 2 + src/test/run-pass/generic-fn.rs | 2 + src/test/run-pass/guards-not-exhaustive.rs | 2 + src/test/run-pass/guards.rs | 2 + src/test/run-pass/issue-12860.rs | 2 + src/test/run-pass/issue-19100.rs | 2 + src/test/run-pass/issue-2288.rs | 3 + src/test/run-pass/issue-2633.rs | 4 + src/test/run-pass/issue-3121.rs | 4 + src/test/run-pass/issue-3563-3.rs | 6 + src/test/run-pass/issue-3743.rs | 2 + src/test/run-pass/issue-3753.rs | 4 + src/test/run-pass/issue-5688.rs | 4 + src/test/run-pass/lang-item-public.rs | 1 + src/test/run-pass/match-arm-statics.rs | 2 + src/test/run-pass/method-self-arg-trait.rs | 2 + src/test/run-pass/method-self-arg.rs | 2 + .../run-pass/monomorphize-abi-alignment.rs | 15 +- src/test/run-pass/multidispatch1.rs | 2 + src/test/run-pass/multidispatch2.rs | 2 + src/test/run-pass/newtype.rs | 9 +- src/test/run-pass/out-pointer-aliasing.rs | 2 + .../run-pass/overloaded-autoderef-order.rs | 4 + src/test/run-pass/packed-struct-vec.rs | 2 + src/test/run-pass/rec-tup.rs | 2 + src/test/run-pass/rec.rs | 2 + .../run-pass/regions-dependent-addr-of.rs | 2 + ...egions-early-bound-used-in-bound-method.rs | 2 + .../regions-early-bound-used-in-bound.rs | 2 + .../regions-early-bound-used-in-type-param.rs | 2 + src/test/run-pass/regions-mock-tcx.rs | 9 + .../self-in-mut-slot-immediate-value.rs | 2 + .../run-pass/shape_intrinsic_tag_then_rec.rs | 67 ----- src/test/run-pass/simd-generics.rs | 2 + src/test/run-pass/small-enum-range-edge.rs | 6 + src/test/run-pass/struct-return.rs | 5 + src/test/run-pass/structured-compare.rs | 2 + src/test/run-pass/tag-variant-disr-val.rs | 2 + src/test/run-pass/trait-coercion-generic.rs | 2 + src/test/run-pass/trait-coercion.rs | 2 + .../run-pass/typeclasses-eq-example-static.rs | 11 +- src/test/run-pass/typeclasses-eq-example.rs | 8 +- src/test/run-pass/ufcs-explicit-self.rs | 4 + .../unboxed-closures-monomorphization.rs | 3 + 277 files changed, 2182 insertions(+), 513 deletions(-) delete mode 100644 src/test/compile-fail/borrowck-loan-local-as-both-mut-and-imm.rs create mode 100644 src/test/compile-fail/opt-in-copy.rs delete mode 100644 src/test/compile-fail/stage0-clone-contravariant-lifetime.rs delete mode 100644 src/test/compile-fail/stage0-cmp.rs delete mode 100644 src/test/run-pass/shape_intrinsic_tag_then_rec.rs diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs index 0a902d970ef..62b757529dc 100644 --- a/src/compiletest/common.rs +++ b/src/compiletest/common.rs @@ -25,6 +25,8 @@ pub enum Mode { Codegen } +impl Copy for Mode {} + impl FromStr for Mode { fn from_str(s: &str) -> Option { match s { diff --git a/src/doc/guide-unsafe.md b/src/doc/guide-unsafe.md index 5b248126c80..bda1b345632 100644 --- a/src/doc/guide-unsafe.md +++ b/src/doc/guide-unsafe.md @@ -661,6 +661,9 @@ extern { fn abort() -> !; } +#[lang = "owned_box"] +pub struct Box(*mut T); + #[lang="exchange_malloc"] unsafe fn allocate(size: uint, _align: uint) -> *mut u8 { let p = libc::malloc(size as libc::size_t) as *mut u8; diff --git a/src/doc/reference.md b/src/doc/reference.md index 9ac4469d549..f6ee5cadbc6 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -1660,6 +1660,7 @@ Implementations are defined with the keyword `impl`. ``` # struct Point {x: f64, y: f64}; +# impl Copy for Point {} # type Surface = int; # struct BoundingBox {x: f64, y: f64, width: f64, height: f64}; # trait Shape { fn draw(&self, Surface); fn bounding_box(&self) -> BoundingBox; } @@ -1669,6 +1670,8 @@ struct Circle { center: Point, } +impl Copy for Circle {} + impl Shape for Circle { fn draw(&self, s: Surface) { do_draw_circle(s, *self); } fn bounding_box(&self) -> BoundingBox { @@ -1791,6 +1794,7 @@ default visibility with the `priv` keyword. When an item is declared as `pub`, it can be thought of as being accessible to the outside world. For example: ``` +# #![allow(missing_copy_implementations)] # fn main() {} // Declare a private struct struct Foo; diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 8b84ecb6904..95c4dff323e 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -466,7 +466,7 @@ impl TypedArena { } let ptr: &mut T = unsafe { - let ptr: &mut T = mem::transmute(self.ptr); + let ptr: &mut T = mem::transmute(self.ptr.clone()); ptr::write(ptr, object); self.ptr.set(self.ptr.get().offset(1)); ptr diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs index e321ef16f66..a4722c340dd 100644 --- a/src/libcollections/binary_heap.rs +++ b/src/libcollections/binary_heap.rs @@ -35,6 +35,8 @@ //! position: uint //! } //! +//! impl Copy for State {} +//! //! // The priority queue depends on `Ord`. //! // Explicitly implement the trait so the queue becomes a min-heap //! // instead of a max-heap. diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index a30bb9e978b..4309e96bec4 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -39,7 +39,12 @@ pub struct DList { } type Link = Option>>; -struct Rawlink { p: *mut T } + +struct Rawlink { + p: *mut T, +} + +impl Copy for Rawlink {} struct Node { next: Link, @@ -59,6 +64,8 @@ impl<'a, T> Clone for Items<'a, T> { fn clone(&self) -> Items<'a, T> { *self } } +impl<'a,T> Copy for Items<'a,T> {} + /// An iterator over mutable references to the items of a `DList`. pub struct MutItems<'a, T:'a> { list: &'a mut DList, diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index 5e77cf66726..28514b99192 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -27,6 +27,8 @@ pub struct EnumSet { bits: uint } +impl Copy for EnumSet {} + impl fmt::Show for EnumSet { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { try!(write!(fmt, "{{")); @@ -269,6 +271,8 @@ mod test { A, B, C } + impl Copy for Foo {} + impl CLike for Foo { fn to_uint(&self) -> uint { *self as uint @@ -477,6 +481,9 @@ mod test { V50, V51, V52, V53, V54, V55, V56, V57, V58, V59, V60, V61, V62, V63, V64, V65, V66, V67, V68, V69, } + + impl Copy for Bar {} + impl CLike for Bar { fn to_uint(&self) -> uint { *self as uint diff --git a/src/libcollections/hash/sip.rs b/src/libcollections/hash/sip.rs index ab69a3ad8b8..9a7aa8c20d3 100644 --- a/src/libcollections/hash/sip.rs +++ b/src/libcollections/hash/sip.rs @@ -43,6 +43,8 @@ pub struct SipState { ntail: uint, // how many bytes in tail are valid } +impl Copy for SipState {} + // sadly, these macro definitions can't appear later, // because they're needed in the following defs; // this design could be improved. @@ -211,6 +213,7 @@ impl Default for SipState { /// `SipHasher` computes the SipHash algorithm from a stream of bytes. #[deriving(Clone)] +#[allow(missing_copy_implementations)] pub struct SipHasher { k0: u64, k1: u64, diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 03b8ea8f20f..c230c48d222 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -91,7 +91,7 @@ use self::Direction::*; use alloc::boxed::Box; use core::borrow::{BorrowFrom, BorrowFromMut, ToOwned}; use core::cmp; -use core::kinds::Sized; +use core::kinds::{Copy, Sized}; use core::mem::size_of; use core::mem; use core::prelude::{Clone, Greater, Iterator, IteratorExt, Less, None, Option}; @@ -177,12 +177,16 @@ impl ElementSwaps { enum Direction { Pos, Neg } +impl Copy for Direction {} + /// An `Index` and `Direction` together. struct SizeDirection { size: uint, dir: Direction, } +impl Copy for SizeDirection {} + impl Iterator<(uint, uint)> for ElementSwaps { #[inline] fn next(&mut self) -> Option<(uint, uint)> { @@ -1482,11 +1486,17 @@ mod tests { fn clone(&self) -> S { self.f.set(self.f.get() + 1); if self.f.get() == 10 { panic!() } - S { f: self.f, boxes: self.boxes.clone() } + S { + f: self.f.clone(), + boxes: self.boxes.clone(), + } } } - let s = S { f: Cell::new(0), boxes: (box 0, Rc::new(0)) }; + let s = S { + f: Cell::new(0), + boxes: (box 0, Rc::new(0)), + }; let _ = Vec::from_elem(100, s); } diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 28027198143..419d7f270ad 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -228,24 +228,32 @@ impl<'a> Iterator for Decompositions<'a> { _ => self.sorted = false } - let decomposer = match self.kind { - Canonical => unicode::char::decompose_canonical, - Compatible => unicode::char::decompose_compatible - }; - if !self.sorted { for ch in self.iter { let buffer = &mut self.buffer; let sorted = &mut self.sorted; - decomposer(ch, |d| { - let class = unicode::char::canonical_combining_class(d); - if class == 0 && !*sorted { - canonical_sort(buffer.as_mut_slice()); - *sorted = true; + { + let callback = |d| { + let class = + unicode::char::canonical_combining_class(d); + if class == 0 && !*sorted { + canonical_sort(buffer.as_mut_slice()); + *sorted = true; + } + buffer.push((d, class)); + }; + match self.kind { + Canonical => { + unicode::char::decompose_canonical(ch, callback) + } + Compatible => { + unicode::char::decompose_compatible(ch, callback) + } } - buffer.push((d, class)); - }); - if *sorted { break } + } + if *sorted { + break + } } } diff --git a/src/libcore/atomic.rs b/src/libcore/atomic.rs index e930f353b52..748f5d774a4 100644 --- a/src/libcore/atomic.rs +++ b/src/libcore/atomic.rs @@ -17,6 +17,7 @@ pub use self::Ordering::*; use intrinsics; use std::kinds::marker; use cell::UnsafeCell; +use kinds::Copy; /// A boolean type which can be safely shared between threads. #[stable] @@ -81,6 +82,8 @@ pub enum Ordering { SeqCst, } +impl Copy for Ordering {} + /// An `AtomicBool` initialized to `false`. #[unstable = "may be renamed, pending conventions for static initalizers"] pub const INIT_ATOMIC_BOOL: AtomicBool = diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 2bebe87a14c..8485e40819b 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -519,3 +519,4 @@ impl Iterator for DefaultEscapedChars { } } } + diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index a5ba2b03b15..87fa44cea66 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -43,9 +43,8 @@ pub use self::Ordering::*; -use kinds::Sized; -use option::Option; -use option::Option::{Some, None}; +use kinds::{Copy, Sized}; +use option::{Option, Some, None}; /// Trait for values that can be compared for equality and inequality. /// @@ -106,6 +105,8 @@ pub enum Ordering { Greater = 1i, } +impl Copy for Ordering {} + impl Ordering { /// Reverse the `Ordering`, so that `Less` becomes `Greater` and /// vice versa. diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 8b2ffd90ef7..88ea811cfd6 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -46,6 +46,8 @@ pub type Result = result::Result<(), Error>; #[experimental = "core and I/O reconciliation may alter this definition"] pub struct Error; +impl Copy for Error {} + /// A collection of methods that are required to format a message into a stream. /// /// This trait is the type which this modules requires when formatting @@ -135,6 +137,8 @@ impl<'a> Argument<'a> { } } +impl<'a> Copy for Argument<'a> {} + impl<'a> Arguments<'a> { /// When using the format_args!() macro, this function is used to generate the /// Arguments structure. diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index a441ced03b2..fa6f48326b5 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -16,6 +16,7 @@ use fmt; use iter::DoubleEndedIteratorExt; +use kinds::Copy; use num::{Int, cast}; use slice::SlicePrelude; @@ -114,6 +115,8 @@ pub struct Radix { base: u8, } +impl Copy for Radix {} + impl Radix { fn new(base: u8) -> Radix { assert!(2 <= base && base <= 36, "the base must be in the range of 2..36: {}", base); @@ -136,6 +139,8 @@ impl GenericRadix for Radix { #[unstable = "may be renamed or move to a different module"] pub struct RadixFmt(T, R); +impl Copy for RadixFmt where T: Copy, R: Copy {} + /// Constructs a radix formatter in the range of `2..36`. /// /// # Example diff --git a/src/libcore/fmt/rt.rs b/src/libcore/fmt/rt.rs index 145e78dc668..748bd0bc4bd 100644 --- a/src/libcore/fmt/rt.rs +++ b/src/libcore/fmt/rt.rs @@ -20,6 +20,7 @@ pub use self::Alignment::*; pub use self::Count::*; pub use self::Position::*; pub use self::Flag::*; +use kinds::Copy; #[doc(hidden)] pub struct Argument<'a> { @@ -27,6 +28,8 @@ pub struct Argument<'a> { pub format: FormatSpec, } +impl<'a> Copy for Argument<'a> {} + #[doc(hidden)] pub struct FormatSpec { pub fill: char, @@ -36,6 +39,8 @@ pub struct FormatSpec { pub width: Count, } +impl Copy for FormatSpec {} + /// Possible alignments that can be requested as part of a formatting directive. #[deriving(PartialEq)] pub enum Alignment { @@ -49,16 +54,22 @@ pub enum Alignment { AlignUnknown, } +impl Copy for Alignment {} + #[doc(hidden)] pub enum Count { CountIs(uint), CountIsParam(uint), CountIsNextParam, CountImplied, } +impl Copy for Count {} + #[doc(hidden)] pub enum Position { ArgumentNext, ArgumentIs(uint) } +impl Copy for Position {} + /// Flags which can be passed to formatting via a directive. /// /// These flags are discovered through the `flags` field of the `Formatter` @@ -78,3 +89,5 @@ pub enum Flag { /// being aware of the sign to be printed. FlagSignAwareZeroPad, } + +impl Copy for Flag {} diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index ece2ac6975e..2fc4d23e7fd 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -42,6 +42,8 @@ #![experimental] #![allow(missing_docs)] +use kinds::Copy; + pub type GlueFn = extern "Rust" fn(*const i8); #[lang="ty_desc"] @@ -59,6 +61,8 @@ pub struct TyDesc { pub name: &'static str, } +impl Copy for TyDesc {} + extern "rust-intrinsic" { // NB: These intrinsics take unsafe pointers because they mutate aliased @@ -539,6 +543,8 @@ pub struct TypeId { t: u64, } +impl Copy for TypeId {} + impl TypeId { /// Returns the `TypeId` of the type this generic function has been instantiated with pub fn of() -> TypeId { diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 49865bd3c7d..ddca9d36bed 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -59,6 +59,7 @@ pub use self::MinMaxResult::*; use clone::Clone; use cmp; use cmp::Ord; +use kinds::Copy; use mem; use num::{ToPrimitive, Int}; use ops::{Add, Deref}; @@ -1166,7 +1167,8 @@ pub struct Cycle { iter: T, } -#[unstable = "trait is unstable"] +impl Copy for Cycle {} + impl> Iterator for Cycle { #[inline] fn next(&mut self) -> Option { @@ -1576,7 +1578,8 @@ pub struct Peekable { peeked: Option, } -#[unstable = "trait is unstable"] +impl Copy for Peekable {} + impl> Iterator for Peekable { #[inline] fn next(&mut self) -> Option { @@ -2115,6 +2118,8 @@ pub struct Counter { step: A, } +impl Copy for Counter {} + /// Creates a new counter with the specified start/step #[inline] #[unstable = "may be renamed"] @@ -2146,6 +2151,8 @@ pub struct Range { one: A, } +impl Copy for Range {} + /// Returns an iterator over the given range [start, stop) (that is, starting /// at start (inclusive), and ending at stop (exclusive)). /// diff --git a/src/libcore/kinds.rs b/src/libcore/kinds.rs index 0c2cb9d5910..f932acffd3c 100644 --- a/src/libcore/kinds.rs +++ b/src/libcore/kinds.rs @@ -91,6 +91,8 @@ pub trait Sync for Sized? { /// implemented using unsafe code. In that case, you may want to embed /// some of the marker types below into your type. pub mod marker { + use super::Copy; + /// A marker type whose type parameter `T` is considered to be /// covariant with respect to the type itself. This is (typically) /// used to indicate that an instance of the type `T` is being stored @@ -132,6 +134,8 @@ pub mod marker { #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct CovariantType; + impl Copy for CovariantType {} + /// A marker type whose type parameter `T` is considered to be /// contravariant with respect to the type itself. This is (typically) /// used to indicate that an instance of the type `T` will be consumed @@ -175,6 +179,8 @@ pub mod marker { #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct ContravariantType; + impl Copy for ContravariantType {} + /// A marker type whose type parameter `T` is considered to be /// invariant with respect to the type itself. This is (typically) /// used to indicate that instances of the type `T` may be read or @@ -200,6 +206,8 @@ pub mod marker { #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct InvariantType; + impl Copy for InvariantType {} + /// As `CovariantType`, but for lifetime parameters. Using /// `CovariantLifetime<'a>` indicates that it is ok to substitute /// a *longer* lifetime for `'a` than the one you originally @@ -220,6 +228,8 @@ pub mod marker { #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct CovariantLifetime<'a>; + impl<'a> Copy for CovariantLifetime<'a> {} + /// As `ContravariantType`, but for lifetime parameters. Using /// `ContravariantLifetime<'a>` indicates that it is ok to /// substitute a *shorter* lifetime for `'a` than the one you @@ -236,6 +246,8 @@ pub mod marker { #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct ContravariantLifetime<'a>; + impl<'a> Copy for ContravariantLifetime<'a> {} + /// As `InvariantType`, but for lifetime parameters. Using /// `InvariantLifetime<'a>` indicates that it is not ok to /// substitute any other lifetime for `'a` besides its original @@ -253,6 +265,7 @@ pub mod marker { /// their instances remain thread-local. #[lang="no_send_bound"] #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)] + #[allow(missing_copy_implementations)] pub struct NoSend; /// A type which is considered "not POD", meaning that it is not @@ -260,6 +273,7 @@ pub mod marker { /// ensure that they are never copied, even if they lack a destructor. #[lang="no_copy_bound"] #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)] + #[allow(missing_copy_implementations)] pub struct NoCopy; /// A type which is considered "not sync", meaning that @@ -267,11 +281,14 @@ pub mod marker { /// shared between tasks. #[lang="no_sync_bound"] #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)] + #[allow(missing_copy_implementations)] pub struct NoSync; /// A type which is considered managed by the GC. This is typically /// embedded in other types. #[lang="managed_bound"] #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)] + #[allow(missing_copy_implementations)] pub struct Managed; } + diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 5ad9462daf2..09d5061a02f 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -56,7 +56,7 @@ html_playground_url = "http://play.rust-lang.org/")] #![no_std] -#![allow(unknown_features)] +#![allow(unknown_features, raw_pointer_deriving)] #![feature(globs, intrinsics, lang_items, macro_rules, phase)] #![feature(simd, unsafe_destructor, slicing_syntax)] #![feature(default_type_params)] diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index e6946c83ceb..3c9b68b350b 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1240,6 +1240,8 @@ pub enum FPCategory { FPNormal, } +impl Copy for FPCategory {} + /// A built-in floating point number. // FIXME(#5527): In a future version of Rust, many of these functions will // become constants. diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index ce774a66381..e16b24923a8 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -90,6 +90,8 @@ pub trait Drop { /// ```rust /// struct Foo; /// +/// impl Copy for Foo {} +/// /// impl Add for Foo { /// fn add(&self, _rhs: &Foo) -> Foo { /// println!("Adding!"); @@ -128,6 +130,8 @@ add_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64) /// ```rust /// struct Foo; /// +/// impl Copy for Foo {} +/// /// impl Sub for Foo { /// fn sub(&self, _rhs: &Foo) -> Foo { /// println!("Subtracting!"); @@ -166,6 +170,8 @@ sub_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64) /// ```rust /// struct Foo; /// +/// impl Copy for Foo {} +/// /// impl Mul for Foo { /// fn mul(&self, _rhs: &Foo) -> Foo { /// println!("Multiplying!"); @@ -204,6 +210,8 @@ mul_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64) /// ``` /// struct Foo; /// +/// impl Copy for Foo {} +/// /// impl Div for Foo { /// fn div(&self, _rhs: &Foo) -> Foo { /// println!("Dividing!"); @@ -242,6 +250,8 @@ div_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64) /// ``` /// struct Foo; /// +/// impl Copy for Foo {} +/// /// impl Rem for Foo { /// fn rem(&self, _rhs: &Foo) -> Foo { /// println!("Remainder-ing!"); @@ -294,6 +304,8 @@ rem_float_impl!(f64, fmod) /// ``` /// struct Foo; /// +/// impl Copy for Foo {} +/// /// impl Neg for Foo { /// fn neg(&self) -> Foo { /// println!("Negating!"); @@ -348,6 +360,8 @@ neg_uint_impl!(u64, i64) /// ``` /// struct Foo; /// +/// impl Copy for Foo {} +/// /// impl Not for Foo { /// fn not(&self) -> Foo { /// println!("Not-ing!"); @@ -387,6 +401,8 @@ not_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64) /// ``` /// struct Foo; /// +/// impl Copy for Foo {} +/// /// impl BitAnd for Foo { /// fn bitand(&self, _rhs: &Foo) -> Foo { /// println!("Bitwise And-ing!"); @@ -425,6 +441,8 @@ bitand_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64) /// ``` /// struct Foo; /// +/// impl Copy for Foo {} +/// /// impl BitOr for Foo { /// fn bitor(&self, _rhs: &Foo) -> Foo { /// println!("Bitwise Or-ing!"); @@ -463,6 +481,8 @@ bitor_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64) /// ``` /// struct Foo; /// +/// impl Copy for Foo {} +/// /// impl BitXor for Foo { /// fn bitxor(&self, _rhs: &Foo) -> Foo { /// println!("Bitwise Xor-ing!"); @@ -501,6 +521,8 @@ bitxor_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64) /// ``` /// struct Foo; /// +/// impl Copy for Foo {} +/// /// impl Shl for Foo { /// fn shl(&self, _rhs: &Foo) -> Foo { /// println!("Shifting left!"); @@ -541,6 +563,8 @@ shl_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64) /// ``` /// struct Foo; /// +/// impl Copy for Foo {} +/// /// impl Shr for Foo { /// fn shr(&self, _rhs: &Foo) -> Foo { /// println!("Shifting right!"); @@ -580,6 +604,8 @@ shr_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64) /// ``` /// struct Foo; /// +/// impl Copy for Foo {} +/// /// impl Index for Foo { /// fn index<'a>(&'a self, _index: &Foo) -> &'a Foo { /// println!("Indexing!"); @@ -608,6 +634,8 @@ pub trait Index for Sized? { /// ``` /// struct Foo; /// +/// impl Copy for Foo {} +/// /// impl IndexMut for Foo { /// fn index_mut<'a>(&'a mut self, _index: &Foo) -> &'a mut Foo { /// println!("Indexing!"); @@ -636,6 +664,8 @@ pub trait IndexMut for Sized? { /// ```ignore /// struct Foo; /// +/// impl Copy for Foo {} +/// /// impl Slice for Foo { /// fn as_slice_<'a>(&'a self) -> &'a Foo { /// println!("Slicing!"); @@ -682,6 +712,8 @@ pub trait Slice for Sized? { /// ```ignore /// struct Foo; /// +/// impl Copy for Foo {} +/// /// impl SliceMut for Foo { /// fn as_mut_slice_<'a>(&'a mut self) -> &'a mut Foo { /// println!("Slicing!"); diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 8ba41c3575f..0a8fa28e52c 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -147,7 +147,9 @@ pub use self::Option::*; use cmp::{Eq, Ord}; use default::Default; -use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, ExactSizeIterator}; +use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator}; +use iter::{ExactSizeIterator}; +use kinds::Copy; use mem; use result::Result; use result::Result::{Ok, Err}; @@ -857,3 +859,6 @@ impl> FromIterator> for Option { } } } + +impl Copy for Option {} + diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 3f6ac49786d..5c61a1ed103 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -437,3 +437,4 @@ impl PartialOrd for *mut T { #[inline] fn ge(&self, other: &*mut T) -> bool { *self >= *other } } + diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs index d156f71462d..db1be94b2b8 100644 --- a/src/libcore/raw.rs +++ b/src/libcore/raw.rs @@ -18,6 +18,7 @@ //! //! Their definition should always match the ABI defined in `rustc::back::abi`. +use kinds::Copy; use mem; use kinds::Sized; @@ -28,6 +29,8 @@ pub struct Slice { pub len: uint, } +impl Copy for Slice {} + /// The representation of a Rust closure #[repr(C)] pub struct Closure { @@ -35,6 +38,8 @@ pub struct Closure { pub env: *mut (), } +impl Copy for Closure {} + /// The representation of a Rust procedure (`proc()`) #[repr(C)] pub struct Procedure { @@ -42,6 +47,8 @@ pub struct Procedure { pub env: *mut (), } +impl Copy for Procedure {} + /// The representation of a Rust trait object. /// /// This struct does not have a `Repr` implementation @@ -52,6 +59,8 @@ pub struct TraitObject { pub vtable: *mut (), } +impl Copy for TraitObject {} + /// This trait is meant to map equivalences between raw structs and their /// corresponding rust values. pub trait Repr for Sized? { diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 0cf8e6affd7..c5d69b16987 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -232,6 +232,7 @@ pub use self::Result::*; +use kinds::Copy; use std::fmt::Show; use slice; use slice::AsSlice; @@ -916,3 +917,7 @@ pub fn fold Copy for Result {} + diff --git a/src/libcore/simd.rs b/src/libcore/simd.rs index 2b6f97cf6a5..369a7106583 100644 --- a/src/libcore/simd.rs +++ b/src/libcore/simd.rs @@ -37,6 +37,8 @@ #![allow(non_camel_case_types)] #![allow(missing_docs)] +use kinds::Copy; + #[experimental] #[simd] #[deriving(Show)] @@ -46,6 +48,8 @@ pub struct i8x16(pub i8, pub i8, pub i8, pub i8, pub i8, pub i8, pub i8, pub i8, pub i8, pub i8, pub i8, pub i8); +impl Copy for i8x16 {} + #[experimental] #[simd] #[deriving(Show)] @@ -53,18 +57,24 @@ pub struct i8x16(pub i8, pub i8, pub i8, pub i8, pub struct i16x8(pub i16, pub i16, pub i16, pub i16, pub i16, pub i16, pub i16, pub i16); +impl Copy for i16x8 {} + #[experimental] #[simd] #[deriving(Show)] #[repr(C)] pub struct i32x4(pub i32, pub i32, pub i32, pub i32); +impl Copy for i32x4 {} + #[experimental] #[simd] #[deriving(Show)] #[repr(C)] pub struct i64x2(pub i64, pub i64); +impl Copy for i64x2 {} + #[experimental] #[simd] #[deriving(Show)] @@ -74,6 +84,8 @@ pub struct u8x16(pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8); +impl Copy for u8x16 {} + #[experimental] #[simd] #[deriving(Show)] @@ -81,26 +93,37 @@ pub struct u8x16(pub u8, pub u8, pub u8, pub u8, pub struct u16x8(pub u16, pub u16, pub u16, pub u16, pub u16, pub u16, pub u16, pub u16); +impl Copy for u16x8 {} + #[experimental] #[simd] #[deriving(Show)] #[repr(C)] pub struct u32x4(pub u32, pub u32, pub u32, pub u32); +impl Copy for u32x4 {} + #[experimental] #[simd] #[deriving(Show)] #[repr(C)] pub struct u64x2(pub u64, pub u64); +impl Copy for u64x2 {} + #[experimental] #[simd] #[deriving(Show)] #[repr(C)] pub struct f32x4(pub f32, pub f32, pub f32, pub f32); +impl Copy for f32x4 {} + #[experimental] #[simd] #[deriving(Show)] #[repr(C)] pub struct f64x2(pub f64, pub f64); + +impl Copy for f64x2 {} + diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index b8df36c91bc..4e3007b55fe 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -41,6 +41,7 @@ use cmp::Ordering::{Less, Equal, Greater}; use cmp; use default::Default; use iter::*; +use kinds::Copy; use num::Int; use ops; use option::Option; @@ -1157,6 +1158,8 @@ impl<'a, T> Items<'a, T> { } } +impl<'a,T> Copy for Items<'a,T> {} + iterator!{struct Items -> *const T, &'a T} #[experimental = "needs review"] @@ -1607,6 +1610,8 @@ pub enum BinarySearchResult { NotFound(uint) } +impl Copy for BinarySearchResult {} + #[experimental = "needs review"] impl BinarySearchResult { /// Converts a `Found` to `Some`, `NotFound` to `None`. @@ -1920,3 +1925,4 @@ impl_int_slice!(u16, i16) impl_int_slice!(u32, i32) impl_int_slice!(u64, i64) impl_int_slice!(uint, int) + diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 1d59567cbe4..8f9eeaddfb5 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -26,7 +26,7 @@ use default::Default; use iter::{Map, Iterator, IteratorExt, DoubleEndedIterator}; use iter::{DoubleEndedIteratorExt, ExactSizeIterator}; use iter::range; -use kinds::Sized; +use kinds::{Copy, Sized}; use mem; use num::Int; use option::Option; @@ -176,6 +176,8 @@ pub struct Chars<'a> { iter: slice::Items<'a, u8> } +impl<'a> Copy for Chars<'a> {} + // Return the initial codepoint accumulator for the first byte. // The first byte is special, only want bottom 5 bits for width 2, 4 bits // for width 3, and 3 bits for width 4 @@ -996,6 +998,8 @@ pub enum Utf16Item { LoneSurrogate(u16) } +impl Copy for Utf16Item {} + impl Utf16Item { /// Convert `self` to a `char`, taking `LoneSurrogate`s to the /// replacement character (U+FFFD). @@ -1139,6 +1143,8 @@ pub struct CharRange { pub next: uint, } +impl Copy for CharRange {} + /// Mask of the value bits of a continuation byte const CONT_MASK: u8 = 0b0011_1111u8; /// Value of the tag bits (tag mask is !CONT_MASK) of a continuation byte @@ -2315,3 +2321,4 @@ impl StrPrelude for str { impl<'a> Default for &'a str { fn default() -> &'a str { "" } } + diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index d88551eb855..db389457a1e 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -44,6 +44,8 @@ pub enum Piece<'a> { NextArgument(Argument<'a>), } +impl<'a> Copy for Piece<'a> {} + /// Representation of an argument specification. #[deriving(PartialEq)] pub struct Argument<'a> { @@ -53,6 +55,8 @@ pub struct Argument<'a> { pub format: FormatSpec<'a>, } +impl<'a> Copy for Argument<'a> {} + /// Specification for the formatting of an argument in the format string. #[deriving(PartialEq)] pub struct FormatSpec<'a> { @@ -72,6 +76,8 @@ pub struct FormatSpec<'a> { pub ty: &'a str } +impl<'a> Copy for FormatSpec<'a> {} + /// Enum describing where an argument for a format can be located. #[deriving(PartialEq)] pub enum Position<'a> { @@ -83,6 +89,8 @@ pub enum Position<'a> { ArgumentNamed(&'a str), } +impl<'a> Copy for Position<'a> {} + /// Enum of alignments which are supported. #[deriving(PartialEq)] pub enum Alignment { @@ -96,6 +104,8 @@ pub enum Alignment { AlignUnknown, } +impl Copy for Alignment {} + /// Various flags which can be applied to format strings. The meaning of these /// flags is defined by the formatters themselves. #[deriving(PartialEq)] @@ -112,6 +122,8 @@ pub enum Flag { FlagSignAwareZeroPad, } +impl Copy for Flag {} + /// A count is used for the precision and width parameters of an integer, and /// can reference either an argument or a literal integer. #[deriving(PartialEq)] @@ -128,6 +140,8 @@ pub enum Count<'a> { CountImplied, } +impl<'a> Copy for Count<'a> {} + /// The parser structure for interpreting the input format string. This is /// modelled as an iterator over `Piece` structures to form a stream of tokens /// being output. diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index ffcc0eb22f6..9174f8e8456 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -97,6 +97,9 @@ use self::HasArg::*; use self::Occur::*; use self::Fail::*; use self::Optval::*; +use self::SplitWithinState::*; +use self::Whitespace::*; +use self::LengthLimit::*; use std::fmt; use std::result::Result::{Err, Ok}; @@ -125,6 +128,8 @@ pub enum HasArg { Maybe, } +impl Copy for HasArg {} + /// Describes how often an option may occur. #[deriving(Clone, PartialEq, Eq)] pub enum Occur { @@ -136,6 +141,8 @@ pub enum Occur { Multi, } +impl Copy for Occur {} + /// A description of a possible option. #[deriving(Clone, PartialEq, Eq)] pub struct Opt { @@ -203,6 +210,19 @@ pub enum Fail { UnexpectedArgument(String), } +/// The type of failure that occurred. +#[deriving(PartialEq, Eq)] +#[allow(missing_docs)] +pub enum FailType { + ArgumentMissing_, + UnrecognizedOption_, + OptionMissing_, + OptionDuplicated_, + UnexpectedArgument_, +} + +impl Copy for FailType {} + /// The result of parsing a command line with a set of options. pub type Result = result::Result; @@ -824,14 +844,17 @@ enum SplitWithinState { B, // words C, // internal and trailing whitespace } +impl Copy for SplitWithinState {} enum Whitespace { Ws, // current char is whitespace Cr // current char is not whitespace } +impl Copy for Whitespace {} enum LengthLimit { UnderLim, // current char makes current substring still fit in limit OverLim // current char makes current substring no longer fit in limit } +impl Copy for LengthLimit {} /// Splits a string into substrings with possibly internal whitespace, @@ -847,9 +870,6 @@ enum LengthLimit { /// sequence longer than the limit. fn each_split_within<'a>(ss: &'a str, lim: uint, it: |&'a str| -> bool) -> bool { - use self::SplitWithinState::*; - use self::Whitespace::*; - use self::LengthLimit::*; // Just for fun, let's write this as a state machine: let mut slice_start = 0; diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index 18e9d832c00..8825099e36c 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -76,6 +76,7 @@ #![allow(non_upper_case_globals)] #![allow(missing_docs)] #![allow(non_snake_case)] +#![allow(raw_pointer_deriving)] extern crate core; @@ -340,12 +341,15 @@ pub mod types { /// variants, because the compiler complains about the repr attribute /// otherwise. #[repr(u8)] + #[allow(missing_copy_implementations)] pub enum c_void { __variant1, __variant2, } + #[allow(missing_copy_implementations)] pub enum FILE {} + #[allow(missing_copy_implementations)] pub enum fpos_t {} } pub mod c99 { @@ -359,7 +363,9 @@ pub mod types { pub type uint64_t = u64; } pub mod posix88 { + #[allow(missing_copy_implementations)] pub enum DIR {} + #[allow(missing_copy_implementations)] pub enum dirent_t {} } pub mod posix01 {} @@ -380,7 +386,7 @@ pub mod types { pub type pthread_t = c_ulong; #[repr(C)] - pub struct glob_t { + #[deriving(Copy)] pub struct glob_t { pub gl_pathc: size_t, pub gl_pathv: *mut *mut c_char, pub gl_offs: size_t, @@ -393,18 +399,18 @@ pub mod types { } #[repr(C)] - pub struct timeval { + #[deriving(Copy)] pub struct timeval { pub tv_sec: time_t, pub tv_usec: suseconds_t, } #[repr(C)] - pub struct timespec { + #[deriving(Copy)] pub struct timespec { pub tv_sec: time_t, pub tv_nsec: c_long, } - pub enum timezone {} + #[deriving(Copy)] pub enum timezone {} pub type sighandler_t = size_t; } @@ -417,29 +423,29 @@ pub mod types { pub type in_port_t = u16; pub type in_addr_t = u32; #[repr(C)] - pub struct sockaddr { + #[deriving(Copy)] pub struct sockaddr { pub sa_family: sa_family_t, pub sa_data: [u8, ..14], } #[repr(C)] - pub struct sockaddr_storage { + #[deriving(Copy)] pub struct sockaddr_storage { pub ss_family: sa_family_t, pub __ss_align: i64, pub __ss_pad2: [u8, ..112], } #[repr(C)] - pub struct sockaddr_in { + #[deriving(Copy)] pub struct sockaddr_in { pub sin_family: sa_family_t, pub sin_port: in_port_t, pub sin_addr: in_addr, pub sin_zero: [u8, ..8], } #[repr(C)] - pub struct in_addr { + #[deriving(Copy)] pub struct in_addr { pub s_addr: in_addr_t, } #[repr(C)] - pub struct sockaddr_in6 { + #[deriving(Copy)] pub struct sockaddr_in6 { pub sin6_family: sa_family_t, pub sin6_port: in_port_t, pub sin6_flowinfo: u32, @@ -447,21 +453,21 @@ pub mod types { pub sin6_scope_id: u32, } #[repr(C)] - pub struct in6_addr { + #[deriving(Copy)] pub struct in6_addr { pub s6_addr: [u16, ..8] } #[repr(C)] - pub struct ip_mreq { + #[deriving(Copy)] pub struct ip_mreq { pub imr_multiaddr: in_addr, pub imr_interface: in_addr, } #[repr(C)] - pub struct ip6_mreq { + #[deriving(Copy)] pub struct ip6_mreq { pub ipv6mr_multiaddr: in6_addr, pub ipv6mr_interface: c_uint, } #[repr(C)] - pub struct addrinfo { + #[deriving(Copy)] pub struct addrinfo { pub ai_flags: c_int, pub ai_family: c_int, pub ai_socktype: c_int, @@ -483,13 +489,13 @@ pub mod types { pub ai_next: *mut addrinfo, } #[repr(C)] - pub struct sockaddr_un { + #[deriving(Copy)] pub struct sockaddr_un { pub sun_family: sa_family_t, pub sun_path: [c_char, ..108] } #[repr(C)] - pub struct ifaddrs { + #[deriving(Copy)] pub struct ifaddrs { pub ifa_next: *mut ifaddrs, pub ifa_name: *mut c_char, pub ifa_flags: c_uint, @@ -572,7 +578,7 @@ pub mod types { pub type blkcnt_t = i32; #[repr(C)] - pub struct stat { + #[deriving(Copy)] pub struct stat { pub st_dev: dev_t, pub __pad1: c_short, pub st_ino: ino_t, @@ -596,13 +602,13 @@ pub mod types { } #[repr(C)] - pub struct utimbuf { + #[deriving(Copy)] pub struct utimbuf { pub actime: time_t, pub modtime: time_t, } #[repr(C)] - pub struct pthread_attr_t { + #[deriving(Copy)] pub struct pthread_attr_t { pub __size: [u32, ..9] } } @@ -617,7 +623,7 @@ pub mod types { pub type blkcnt_t = u32; #[repr(C)] - pub struct stat { + #[deriving(Copy)] pub struct stat { pub st_dev: c_ulonglong, pub __pad0: [c_uchar, ..4], pub __st_ino: ino_t, @@ -640,13 +646,13 @@ pub mod types { } #[repr(C)] - pub struct utimbuf { + #[deriving(Copy)] pub struct utimbuf { pub actime: time_t, pub modtime: time_t, } #[repr(C)] - pub struct pthread_attr_t { + #[deriving(Copy)] pub struct pthread_attr_t { pub __size: [u32, ..9] } } @@ -662,7 +668,7 @@ pub mod types { pub type blkcnt_t = i32; #[repr(C)] - pub struct stat { + #[deriving(Copy)] pub struct stat { pub st_dev: c_ulong, pub st_pad1: [c_long, ..3], pub st_ino: ino_t, @@ -686,13 +692,13 @@ pub mod types { } #[repr(C)] - pub struct utimbuf { + #[deriving(Copy)] pub struct utimbuf { pub actime: time_t, pub modtime: time_t, } #[repr(C)] - pub struct pthread_attr_t { + #[deriving(Copy)] pub struct pthread_attr_t { pub __size: [u32, ..9] } } @@ -701,7 +707,7 @@ pub mod types { pub mod extra { use types::os::arch::c95::{c_ushort, c_int, c_uchar}; #[repr(C)] - pub struct sockaddr_ll { + #[deriving(Copy)] pub struct sockaddr_ll { pub sll_family: c_ushort, pub sll_protocol: c_ushort, pub sll_ifindex: c_int, @@ -764,7 +770,7 @@ pub mod types { pub type blksize_t = i64; pub type blkcnt_t = i64; #[repr(C)] - pub struct stat { + #[deriving(Copy)] pub struct stat { pub st_dev: dev_t, pub st_ino: ino_t, pub st_nlink: nlink_t, @@ -786,13 +792,13 @@ pub mod types { } #[repr(C)] - pub struct utimbuf { + #[deriving(Copy)] pub struct utimbuf { pub actime: time_t, pub modtime: time_t, } #[repr(C)] - pub struct pthread_attr_t { + #[deriving(Copy)] pub struct pthread_attr_t { pub __size: [u64, ..7] } } @@ -802,7 +808,7 @@ pub mod types { } pub mod extra { use types::os::arch::c95::{c_ushort, c_int, c_uchar}; - pub struct sockaddr_ll { + #[deriving(Copy)] pub struct sockaddr_ll { pub sll_family: c_ushort, pub sll_protocol: c_ushort, pub sll_ifindex: c_int, @@ -828,7 +834,7 @@ pub mod types { pub type pthread_t = uintptr_t; #[repr(C)] - pub struct glob_t { + #[deriving(Copy)] pub struct glob_t { pub gl_pathc: size_t, pub __unused1: size_t, pub gl_offs: size_t, @@ -845,18 +851,18 @@ pub mod types { } #[repr(C)] - pub struct timeval { + #[deriving(Copy)] pub struct timeval { pub tv_sec: time_t, pub tv_usec: suseconds_t, } #[repr(C)] - pub struct timespec { + #[deriving(Copy)] pub struct timespec { pub tv_sec: time_t, pub tv_nsec: c_long, } - pub enum timezone {} + #[deriving(Copy)] pub enum timezone {} pub type sighandler_t = size_t; } @@ -869,13 +875,13 @@ pub mod types { pub type in_port_t = u16; pub type in_addr_t = u32; #[repr(C)] - pub struct sockaddr { + #[deriving(Copy)] pub struct sockaddr { pub sa_len: u8, pub sa_family: sa_family_t, pub sa_data: [u8, ..14], } #[repr(C)] - pub struct sockaddr_storage { + #[deriving(Copy)] pub struct sockaddr_storage { pub ss_len: u8, pub ss_family: sa_family_t, pub __ss_pad1: [u8, ..6], @@ -883,7 +889,7 @@ pub mod types { pub __ss_pad2: [u8, ..112], } #[repr(C)] - pub struct sockaddr_in { + #[deriving(Copy)] pub struct sockaddr_in { pub sin_len: u8, pub sin_family: sa_family_t, pub sin_port: in_port_t, @@ -891,11 +897,11 @@ pub mod types { pub sin_zero: [u8, ..8], } #[repr(C)] - pub struct in_addr { + #[deriving(Copy)] pub struct in_addr { pub s_addr: in_addr_t, } #[repr(C)] - pub struct sockaddr_in6 { + #[deriving(Copy)] pub struct sockaddr_in6 { pub sin6_len: u8, pub sin6_family: sa_family_t, pub sin6_port: in_port_t, @@ -904,21 +910,21 @@ pub mod types { pub sin6_scope_id: u32, } #[repr(C)] - pub struct in6_addr { + #[deriving(Copy)] pub struct in6_addr { pub s6_addr: [u16, ..8] } #[repr(C)] - pub struct ip_mreq { + #[deriving(Copy)] pub struct ip_mreq { pub imr_multiaddr: in_addr, pub imr_interface: in_addr, } #[repr(C)] - pub struct ip6_mreq { + #[deriving(Copy)] pub struct ip6_mreq { pub ipv6mr_multiaddr: in6_addr, pub ipv6mr_interface: c_uint, } #[repr(C)] - pub struct addrinfo { + #[deriving(Copy)] pub struct addrinfo { pub ai_flags: c_int, pub ai_family: c_int, pub ai_socktype: c_int, @@ -929,13 +935,13 @@ pub mod types { pub ai_next: *mut addrinfo, } #[repr(C)] - pub struct sockaddr_un { + #[deriving(Copy)] pub struct sockaddr_un { pub sun_len: u8, pub sun_family: sa_family_t, pub sun_path: [c_char, ..104] } #[repr(C)] - pub struct ifaddrs { + #[deriving(Copy)] pub struct ifaddrs { pub ifa_next: *mut ifaddrs, pub ifa_name: *mut c_char, pub ifa_flags: c_uint, @@ -1002,7 +1008,7 @@ pub mod types { pub type blkcnt_t = i64; pub type fflags_t = u32; #[repr(C)] - pub struct stat { + #[deriving(Copy)] pub struct stat { pub st_dev: dev_t, pub st_ino: ino_t, pub st_mode: mode_t, @@ -1028,7 +1034,7 @@ pub mod types { } #[repr(C)] - pub struct utimbuf { + #[deriving(Copy)] pub struct utimbuf { pub actime: time_t, pub modtime: time_t, } @@ -1056,7 +1062,7 @@ pub mod types { pub type pthread_t = uintptr_t; #[repr(C)] - pub struct glob_t { + #[deriving(Copy)] pub struct glob_t { pub gl_pathc: size_t, pub __unused1: size_t, pub gl_offs: size_t, @@ -1073,18 +1079,18 @@ pub mod types { } #[repr(C)] - pub struct timeval { + #[deriving(Copy)] pub struct timeval { pub tv_sec: time_t, pub tv_usec: suseconds_t, } #[repr(C)] - pub struct timespec { + #[deriving(Copy)] pub struct timespec { pub tv_sec: time_t, pub tv_nsec: c_long, } - pub enum timezone {} + #[deriving(Copy)] pub enum timezone {} pub type sighandler_t = size_t; } @@ -1096,13 +1102,13 @@ pub mod types { pub type in_port_t = u16; pub type in_addr_t = u32; #[repr(C)] - pub struct sockaddr { + #[deriving(Copy)] pub struct sockaddr { pub sa_len: u8, pub sa_family: sa_family_t, pub sa_data: [u8, ..14], } #[repr(C)] - pub struct sockaddr_storage { + #[deriving(Copy)] pub struct sockaddr_storage { pub ss_len: u8, pub ss_family: sa_family_t, pub __ss_pad1: [u8, ..6], @@ -1110,7 +1116,7 @@ pub mod types { pub __ss_pad2: [u8, ..112], } #[repr(C)] - pub struct sockaddr_in { + #[deriving(Copy)] pub struct sockaddr_in { pub sin_len: u8, pub sin_family: sa_family_t, pub sin_port: in_port_t, @@ -1118,11 +1124,11 @@ pub mod types { pub sin_zero: [u8, ..8], } #[repr(C)] - pub struct in_addr { + #[deriving(Copy)] pub struct in_addr { pub s_addr: in_addr_t, } #[repr(C)] - pub struct sockaddr_in6 { + #[deriving(Copy)] pub struct sockaddr_in6 { pub sin6_len: u8, pub sin6_family: sa_family_t, pub sin6_port: in_port_t, @@ -1131,21 +1137,21 @@ pub mod types { pub sin6_scope_id: u32, } #[repr(C)] - pub struct in6_addr { + #[deriving(Copy)] pub struct in6_addr { pub s6_addr: [u16, ..8] } #[repr(C)] - pub struct ip_mreq { + #[deriving(Copy)] pub struct ip_mreq { pub imr_multiaddr: in_addr, pub imr_interface: in_addr, } #[repr(C)] - pub struct ip6_mreq { + #[deriving(Copy)] pub struct ip6_mreq { pub ipv6mr_multiaddr: in6_addr, pub ipv6mr_interface: c_uint, } #[repr(C)] - pub struct addrinfo { + #[deriving(Copy)] pub struct addrinfo { pub ai_flags: c_int, pub ai_family: c_int, pub ai_socktype: c_int, @@ -1156,7 +1162,7 @@ pub mod types { pub ai_next: *mut addrinfo, } #[repr(C)] - pub struct sockaddr_un { + #[deriving(Copy)] pub struct sockaddr_un { pub sun_len: u8, pub sun_family: sa_family_t, pub sun_path: [c_char, ..104] @@ -1219,7 +1225,7 @@ pub mod types { pub type fflags_t = u32; #[repr(C)] - pub struct stat { + #[deriving(Copy)] pub struct stat { pub st_ino: ino_t, pub st_nlink: nlink_t, pub st_dev: dev_t, @@ -1244,7 +1250,7 @@ pub mod types { pub st_qspare2: int64_t, } #[repr(C)] - pub struct utimbuf { + #[deriving(Copy)] pub struct utimbuf { pub actime: time_t, pub modtime: time_t, } @@ -1271,7 +1277,7 @@ pub mod types { // pub Note: this is the struct called stat64 in Windows. Not stat, // nor stati64. #[repr(C)] - pub struct stat { + #[deriving(Copy)] pub struct stat { pub st_dev: dev_t, pub st_ino: ino_t, pub st_mode: u16, @@ -1287,24 +1293,24 @@ pub mod types { // note that this is called utimbuf64 in Windows #[repr(C)] - pub struct utimbuf { + #[deriving(Copy)] pub struct utimbuf { pub actime: time64_t, pub modtime: time64_t, } #[repr(C)] - pub struct timeval { + #[deriving(Copy)] pub struct timeval { pub tv_sec: c_long, pub tv_usec: c_long, } #[repr(C)] - pub struct timespec { + #[deriving(Copy)] pub struct timespec { pub tv_sec: time_t, pub tv_nsec: c_long, } - pub enum timezone {} + #[deriving(Copy)] pub enum timezone {} } pub mod bsd44 { @@ -1317,30 +1323,30 @@ pub mod types { pub type in_port_t = u16; pub type in_addr_t = u32; #[repr(C)] - pub struct sockaddr { + #[deriving(Copy)] pub struct sockaddr { pub sa_family: sa_family_t, pub sa_data: [u8, ..14], } #[repr(C)] - pub struct sockaddr_storage { + #[deriving(Copy)] pub struct sockaddr_storage { pub ss_family: sa_family_t, pub __ss_pad1: [u8, ..6], pub __ss_align: i64, pub __ss_pad2: [u8, ..112], } #[repr(C)] - pub struct sockaddr_in { + #[deriving(Copy)] pub struct sockaddr_in { pub sin_family: sa_family_t, pub sin_port: in_port_t, pub sin_addr: in_addr, pub sin_zero: [u8, ..8], } #[repr(C)] - pub struct in_addr { + #[deriving(Copy)] pub struct in_addr { pub s_addr: in_addr_t, } #[repr(C)] - pub struct sockaddr_in6 { + #[deriving(Copy)] pub struct sockaddr_in6 { pub sin6_family: sa_family_t, pub sin6_port: in_port_t, pub sin6_flowinfo: u32, @@ -1348,21 +1354,21 @@ pub mod types { pub sin6_scope_id: u32, } #[repr(C)] - pub struct in6_addr { + #[deriving(Copy)] pub struct in6_addr { pub s6_addr: [u16, ..8] } #[repr(C)] - pub struct ip_mreq { + #[deriving(Copy)] pub struct ip_mreq { pub imr_multiaddr: in_addr, pub imr_interface: in_addr, } #[repr(C)] - pub struct ip6_mreq { + #[deriving(Copy)] pub struct ip6_mreq { pub ipv6mr_multiaddr: in6_addr, pub ipv6mr_interface: c_uint, } #[repr(C)] - pub struct addrinfo { + #[deriving(Copy)] pub struct addrinfo { pub ai_flags: c_int, pub ai_family: c_int, pub ai_socktype: c_int, @@ -1373,7 +1379,7 @@ pub mod types { pub ai_next: *mut addrinfo, } #[repr(C)] - pub struct sockaddr_un { + #[deriving(Copy)] pub struct sockaddr_un { pub sun_family: sa_family_t, pub sun_path: [c_char, ..108] } @@ -1501,7 +1507,7 @@ pub mod types { pub type LPCH = *mut CHAR; #[repr(C)] - pub struct SECURITY_ATTRIBUTES { + #[deriving(Copy)] pub struct SECURITY_ATTRIBUTES { pub nLength: DWORD, pub lpSecurityDescriptor: LPVOID, pub bInheritHandle: BOOL, @@ -1525,7 +1531,7 @@ pub mod types { pub type int64 = i64; #[repr(C)] - pub struct STARTUPINFO { + #[deriving(Copy)] pub struct STARTUPINFO { pub cb: DWORD, pub lpReserved: LPWSTR, pub lpDesktop: LPWSTR, @@ -1548,7 +1554,7 @@ pub mod types { pub type LPSTARTUPINFO = *mut STARTUPINFO; #[repr(C)] - pub struct PROCESS_INFORMATION { + #[deriving(Copy)] pub struct PROCESS_INFORMATION { pub hProcess: HANDLE, pub hThread: HANDLE, pub dwProcessId: DWORD, @@ -1557,7 +1563,7 @@ pub mod types { pub type LPPROCESS_INFORMATION = *mut PROCESS_INFORMATION; #[repr(C)] - pub struct SYSTEM_INFO { + #[deriving(Copy)] pub struct SYSTEM_INFO { pub wProcessorArchitecture: WORD, pub wReserved: WORD, pub dwPageSize: DWORD, @@ -1573,7 +1579,7 @@ pub mod types { pub type LPSYSTEM_INFO = *mut SYSTEM_INFO; #[repr(C)] - pub struct MEMORY_BASIC_INFORMATION { + #[deriving(Copy)] pub struct MEMORY_BASIC_INFORMATION { pub BaseAddress: LPVOID, pub AllocationBase: LPVOID, pub AllocationProtect: DWORD, @@ -1585,7 +1591,7 @@ pub mod types { pub type LPMEMORY_BASIC_INFORMATION = *mut MEMORY_BASIC_INFORMATION; #[repr(C)] - pub struct OVERLAPPED { + #[deriving(Copy)] pub struct OVERLAPPED { pub Internal: *mut c_ulong, pub InternalHigh: *mut c_ulong, pub Offset: DWORD, @@ -1596,7 +1602,7 @@ pub mod types { pub type LPOVERLAPPED = *mut OVERLAPPED; #[repr(C)] - pub struct FILETIME { + #[deriving(Copy)] pub struct FILETIME { pub dwLowDateTime: DWORD, pub dwHighDateTime: DWORD, } @@ -1604,7 +1610,7 @@ pub mod types { pub type LPFILETIME = *mut FILETIME; #[repr(C)] - pub struct GUID { + #[deriving(Copy)] pub struct GUID { pub Data1: DWORD, pub Data2: WORD, pub Data3: WORD, @@ -1612,7 +1618,7 @@ pub mod types { } #[repr(C)] - pub struct WSAPROTOCOLCHAIN { + #[deriving(Copy)] pub struct WSAPROTOCOLCHAIN { pub ChainLen: c_int, pub ChainEntries: [DWORD, ..MAX_PROTOCOL_CHAIN as uint], } @@ -1620,7 +1626,7 @@ pub mod types { pub type LPWSAPROTOCOLCHAIN = *mut WSAPROTOCOLCHAIN; #[repr(C)] - pub struct WSAPROTOCOL_INFO { + #[deriving(Copy)] pub struct WSAPROTOCOL_INFO { pub dwServiceFlags1: DWORD, pub dwServiceFlags2: DWORD, pub dwServiceFlags3: DWORD, @@ -1648,7 +1654,7 @@ pub mod types { pub type GROUP = c_uint; #[repr(C)] - pub struct WIN32_FIND_DATAW { + #[deriving(Copy)] pub struct WIN32_FIND_DATAW { pub dwFileAttributes: DWORD, pub ftCreationTime: FILETIME, pub ftLastAccessTime: FILETIME, @@ -1671,14 +1677,14 @@ pub mod types { pub mod common { pub mod posix01 { use types::common::c95::c_void; - use types::os::arch::c95::{c_char, c_int, size_t, - time_t, suseconds_t, c_long}; + use types::os::arch::c95::{c_char, c_int, size_t, time_t}; + use types::os::arch::c95::{suseconds_t, c_long}; use types::os::arch::c99::{uintptr_t}; pub type pthread_t = uintptr_t; #[repr(C)] - pub struct glob_t { + #[deriving(Copy)] pub struct glob_t { pub gl_pathc: size_t, pub __unused1: c_int, pub gl_offs: size_t, @@ -1695,18 +1701,18 @@ pub mod types { } #[repr(C)] - pub struct timeval { + #[deriving(Copy)] pub struct timeval { pub tv_sec: time_t, pub tv_usec: suseconds_t, } #[repr(C)] - pub struct timespec { + #[deriving(Copy)] pub struct timespec { pub tv_sec: time_t, pub tv_nsec: c_long, } - pub enum timezone {} + #[deriving(Copy)] pub enum timezone {} pub type sighandler_t = size_t; } @@ -1720,33 +1726,37 @@ pub mod types { pub type in_port_t = u16; pub type in_addr_t = u32; #[repr(C)] - pub struct sockaddr { + #[deriving(Copy)] pub struct sockaddr { pub sa_len: u8, pub sa_family: sa_family_t, pub sa_data: [u8, ..14], } + #[repr(C)] - pub struct sockaddr_storage { + #[deriving(Copy)] pub struct sockaddr_storage { pub ss_len: u8, pub ss_family: sa_family_t, pub __ss_pad1: [u8, ..6], pub __ss_align: i64, pub __ss_pad2: [u8, ..112], } + #[repr(C)] - pub struct sockaddr_in { + #[deriving(Copy)] pub struct sockaddr_in { pub sin_len: u8, pub sin_family: sa_family_t, pub sin_port: in_port_t, pub sin_addr: in_addr, pub sin_zero: [u8, ..8], } + #[repr(C)] - pub struct in_addr { + #[deriving(Copy)] pub struct in_addr { pub s_addr: in_addr_t, } + #[repr(C)] - pub struct sockaddr_in6 { + #[deriving(Copy)] pub struct sockaddr_in6 { pub sin6_len: u8, pub sin6_family: sa_family_t, pub sin6_port: in_port_t, @@ -1754,22 +1764,26 @@ pub mod types { pub sin6_addr: in6_addr, pub sin6_scope_id: u32, } + #[repr(C)] - pub struct in6_addr { + #[deriving(Copy)] pub struct in6_addr { pub s6_addr: [u16, ..8] } + #[repr(C)] - pub struct ip_mreq { + #[deriving(Copy)] pub struct ip_mreq { pub imr_multiaddr: in_addr, pub imr_interface: in_addr, } + #[repr(C)] - pub struct ip6_mreq { + #[deriving(Copy)] pub struct ip6_mreq { pub ipv6mr_multiaddr: in6_addr, pub ipv6mr_interface: c_uint, } + #[repr(C)] - pub struct addrinfo { + #[deriving(Copy)] pub struct addrinfo { pub ai_flags: c_int, pub ai_family: c_int, pub ai_socktype: c_int, @@ -1779,14 +1793,16 @@ pub mod types { pub ai_addr: *mut sockaddr, pub ai_next: *mut addrinfo, } + #[repr(C)] - pub struct sockaddr_un { + #[deriving(Copy)] pub struct sockaddr_un { pub sun_len: u8, pub sun_family: sa_family_t, pub sun_path: [c_char, ..104] } + #[repr(C)] - pub struct ifaddrs { + #[deriving(Copy)] pub struct ifaddrs { pub ifa_next: *mut ifaddrs, pub ifa_name: *mut c_char, pub ifa_flags: c_uint, @@ -1849,7 +1865,7 @@ pub mod types { pub type blkcnt_t = i32; #[repr(C)] - pub struct stat { + #[deriving(Copy)] pub struct stat { pub st_dev: dev_t, pub st_mode: mode_t, pub st_nlink: nlink_t, @@ -1875,13 +1891,13 @@ pub mod types { } #[repr(C)] - pub struct utimbuf { + #[deriving(Copy)] pub struct utimbuf { pub actime: time_t, pub modtime: time_t, } #[repr(C)] - pub struct pthread_attr_t { + #[deriving(Copy)] pub struct pthread_attr_t { pub __sig: c_long, pub __opaque: [c_char, ..36] } @@ -1892,7 +1908,7 @@ pub mod types { } pub mod extra { #[repr(C)] - pub struct mach_timebase_info { + #[deriving(Copy)] pub struct mach_timebase_info { pub numer: u32, pub denom: u32, } @@ -1953,7 +1969,7 @@ pub mod types { pub type blkcnt_t = i32; #[repr(C)] - pub struct stat { + #[deriving(Copy)] pub struct stat { pub st_dev: dev_t, pub st_mode: mode_t, pub st_nlink: nlink_t, @@ -1979,13 +1995,13 @@ pub mod types { } #[repr(C)] - pub struct utimbuf { + #[deriving(Copy)] pub struct utimbuf { pub actime: time_t, pub modtime: time_t, } #[repr(C)] - pub struct pthread_attr_t { + #[deriving(Copy)] pub struct pthread_attr_t { pub __sig: c_long, pub __opaque: [c_char, ..56] } @@ -1996,7 +2012,7 @@ pub mod types { } pub mod extra { #[repr(C)] - pub struct mach_timebase_info { + #[deriving(Copy)] pub struct mach_timebase_info { pub numer: u32, pub denom: u32, } @@ -4990,3 +5006,9 @@ pub mod funcs { pub fn issue_14344_workaround() {} // FIXME #14344 force linkage to happen correctly #[test] fn work_on_windows() { } // FIXME #10872 needed for a happy windows + +#[doc(hidden)] +#[cfg(not(test))] +mod std { + pub use core::kinds; +} diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs index 5642ec91ba3..8b79078eac6 100644 --- a/src/liblog/lib.rs +++ b/src/liblog/lib.rs @@ -234,6 +234,8 @@ struct DefaultLogger { #[deriving(PartialEq, PartialOrd)] pub struct LogLevel(pub u32); +impl Copy for LogLevel {} + impl fmt::Show for LogLevel { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let LogLevel(level) = *self; @@ -344,6 +346,8 @@ pub struct LogLocation { pub line: uint, } +impl Copy for LogLocation {} + /// Tests whether a given module's name is enabled for a particular level of /// logging. This is the second layer of defense about determining whether a /// module's log statement should be emitted or not. diff --git a/src/librand/chacha.rs b/src/librand/chacha.rs index 2693f183644..83a410674ee 100644 --- a/src/librand/chacha.rs +++ b/src/librand/chacha.rs @@ -35,6 +35,8 @@ pub struct ChaChaRng { index: uint, // Index into state } +impl Copy for ChaChaRng {} + static EMPTY: ChaChaRng = ChaChaRng { buffer: [0, ..STATE_WORDS], state: [0, ..STATE_WORDS], diff --git a/src/librand/distributions/exponential.rs b/src/librand/distributions/exponential.rs index d874f1deed3..9a9f31e9339 100644 --- a/src/librand/distributions/exponential.rs +++ b/src/librand/distributions/exponential.rs @@ -10,6 +10,7 @@ //! The exponential distribution. +use core::kinds::Copy; use core::num::Float; use {Rng, Rand}; @@ -31,6 +32,8 @@ use distributions::{ziggurat, ziggurat_tables, Sample, IndependentSample}; /// College, Oxford pub struct Exp1(pub f64); +impl Copy for Exp1 {} + // This could be done via `-rng.gen::().ln()` but that is slower. impl Rand for Exp1 { #[inline] @@ -71,6 +74,8 @@ pub struct Exp { lambda_inverse: f64 } +impl Copy for Exp {} + impl Exp { /// Construct a new `Exp` with the given shape parameter /// `lambda`. Panics if `lambda <= 0`. diff --git a/src/librand/distributions/normal.rs b/src/librand/distributions/normal.rs index b3dc20819bc..f5261f1db82 100644 --- a/src/librand/distributions/normal.rs +++ b/src/librand/distributions/normal.rs @@ -10,6 +10,7 @@ //! The normal and derived distributions. +use core::kinds::Copy; use core::num::Float; use {Rng, Rand, Open01}; @@ -30,6 +31,8 @@ use distributions::{ziggurat, ziggurat_tables, Sample, IndependentSample}; /// College, Oxford pub struct StandardNormal(pub f64); +impl Copy for StandardNormal {} + impl Rand for StandardNormal { fn rand(rng: &mut R) -> StandardNormal { #[inline] @@ -88,6 +91,8 @@ pub struct Normal { std_dev: f64, } +impl Copy for Normal {} + impl Normal { /// Construct a new `Normal` distribution with the given mean and /// standard deviation. @@ -134,6 +139,8 @@ pub struct LogNormal { norm: Normal } +impl Copy for LogNormal {} + impl LogNormal { /// Construct a new `LogNormal` distribution with the given mean /// and standard deviation. diff --git a/src/librand/isaac.rs b/src/librand/isaac.rs index 517b50c49c7..2c1853b1951 100644 --- a/src/librand/isaac.rs +++ b/src/librand/isaac.rs @@ -37,6 +37,9 @@ pub struct IsaacRng { b: u32, c: u32 } + +impl Copy for IsaacRng {} + static EMPTY: IsaacRng = IsaacRng { cnt: 0, rsl: [0, ..RAND_SIZE_UINT], @@ -271,6 +274,8 @@ pub struct Isaac64Rng { c: u64, } +impl Copy for Isaac64Rng {} + static EMPTY_64: Isaac64Rng = Isaac64Rng { cnt: 0, rsl: [0, .. RAND_SIZE_64], diff --git a/src/librand/lib.rs b/src/librand/lib.rs index de40ee4893d..d357f247f1b 100644 --- a/src/librand/lib.rs +++ b/src/librand/lib.rs @@ -377,6 +377,7 @@ pub trait SeedableRng: Rng { /// [1]: Marsaglia, George (July 2003). ["Xorshift /// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of /// Statistical Software*. Vol. 8 (Issue 14). +#[allow(missing_copy_implementations)] pub struct XorShiftRng { x: u32, y: u32, @@ -384,6 +385,17 @@ pub struct XorShiftRng { w: u32, } +impl Clone for XorShiftRng { + fn clone(&self) -> XorShiftRng { + XorShiftRng { + x: self.x, + y: self.y, + z: self.z, + w: self.w, + } + } +} + impl XorShiftRng { /// Creates a new XorShiftRng instance which is not seeded. /// diff --git a/src/librand/reseeding.rs b/src/librand/reseeding.rs index 64c6b1739eb..88c870579e6 100644 --- a/src/librand/reseeding.rs +++ b/src/librand/reseeding.rs @@ -135,6 +135,8 @@ pub trait Reseeder { /// replacing the RNG with the result of a `Default::default` call. pub struct ReseedWithDefault; +impl Copy for ReseedWithDefault {} + impl Reseeder for ReseedWithDefault { fn reseed(&mut self, rng: &mut R) { *rng = Default::default(); diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index f65c4f4e3ed..426a987d25d 100644 --- a/src/librbml/lib.rs +++ b/src/librbml/lib.rs @@ -47,6 +47,8 @@ pub struct Doc<'a> { pub end: uint, } +impl<'doc> Copy for Doc<'doc> {} + impl<'doc> Doc<'doc> { pub fn new(data: &'doc [u8]) -> Doc<'doc> { Doc { data: data, start: 0u, end: data.len() } @@ -104,6 +106,8 @@ pub enum EbmlEncoderTag { EsLabel, // Used only when debugging } +impl Copy for EbmlEncoderTag {} + #[deriving(Show)] pub enum Error { IntTooBig(uint), @@ -151,6 +155,8 @@ pub mod reader { pub next: uint } + impl Copy for Res {} + #[inline(never)] fn vuint_at_slow(data: &[u8], start: uint) -> DecodeResult { let a = data[start]; diff --git a/src/libregex/parse.rs b/src/libregex/parse.rs index 5cd833e2797..55e533aadee 100644 --- a/src/libregex/parse.rs +++ b/src/libregex/parse.rs @@ -83,6 +83,8 @@ pub enum Greed { Ungreedy, } +impl Copy for Greed {} + impl Greed { pub fn is_greedy(&self) -> bool { match *self { diff --git a/src/libregex/re.rs b/src/libregex/re.rs index 58ce72a3173..2a1fda06431 100644 --- a/src/libregex/re.rs +++ b/src/libregex/re.rs @@ -135,8 +135,12 @@ pub struct ExNative { pub prog: fn(MatchKind, &str, uint, uint) -> Vec> } +impl Copy for ExNative {} + impl Clone for ExNative { - fn clone(&self) -> ExNative { *self } + fn clone(&self) -> ExNative { + *self + } } impl fmt::Show for Regex { @@ -917,7 +921,7 @@ fn exec_slice(re: &Regex, which: MatchKind, input: &str, s: uint, e: uint) -> CaptureLocs { match *re { Dynamic(ExDynamic { ref prog, .. }) => vm::run(which, prog, input, s, e), - Native(ExNative { prog, .. }) => prog(which, input, s, e), + Native(ExNative { ref prog, .. }) => (*prog)(which, input, s, e), } } diff --git a/src/libregex/vm.rs b/src/libregex/vm.rs index 4315c0f7b40..44cf2249b8e 100644 --- a/src/libregex/vm.rs +++ b/src/libregex/vm.rs @@ -60,6 +60,8 @@ pub enum MatchKind { Submatches, } +impl Copy for MatchKind {} + /// Runs an NFA simulation on the compiled expression given on the search text /// `input`. The search begins at byte index `start` and ends at byte index /// `end`. (The range is specified here so that zero-width assertions will work @@ -107,6 +109,8 @@ pub enum StepState { StepContinue, } +impl Copy for StepState {} + impl<'r, 't> Nfa<'r, 't> { fn run(&mut self) -> CaptureLocs { let ncaps = match self.which { diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index c474820c3c9..e19fa01b2e4 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -28,6 +28,7 @@ use self::MethodContext::*; use metadata::csearch; use middle::def::*; +use middle::subst::Substs; use middle::ty::{mod, Ty}; use middle::{def, pat_util, stability}; use middle::const_eval::{eval_const_expr_partial, const_int, const_uint}; @@ -40,11 +41,12 @@ use std::collections::hash_map::{Occupied, Vacant}; use std::num::SignedInt; use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64}; use syntax::{abi, ast, ast_map}; -use syntax::ast_util::{mod, is_shift_binop}; +use syntax::ast_util::is_shift_binop; use syntax::attr::{mod, AttrMetaMethods}; use syntax::codemap::{Span, DUMMY_SP}; use syntax::parse::token; use syntax::ast::{TyI, TyU, TyI8, TyU8, TyI16, TyU16, TyI32, TyU32, TyI64, TyU64}; +use syntax::ast_util; use syntax::ptr::P; use syntax::visit::{mod, Visitor}; @@ -53,6 +55,8 @@ declare_lint!(WHILE_TRUE, Warn, pub struct WhileTrue; +impl Copy for WhileTrue {} + impl LintPass for WhileTrue { fn get_lints(&self) -> LintArray { lint_array!(WHILE_TRUE) @@ -75,6 +79,8 @@ declare_lint!(UNUSED_TYPECASTS, Allow, pub struct UnusedCasts; +impl Copy for UnusedCasts {} + impl LintPass for UnusedCasts { fn get_lints(&self) -> LintArray { lint_array!(UNUSED_TYPECASTS) @@ -107,6 +113,8 @@ pub struct TypeLimits { negated_expr_id: ast::NodeId, } +impl Copy for TypeLimits {} + impl TypeLimits { pub fn new() -> TypeLimits { TypeLimits { @@ -415,6 +423,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ImproperCTypesVisitor<'a, 'tcx> { pub struct ImproperCTypes; +impl Copy for ImproperCTypes {} + impl LintPass for ImproperCTypes { fn get_lints(&self) -> LintArray { lint_array!(IMPROPER_CTYPES) @@ -454,6 +464,8 @@ declare_lint!(BOX_POINTERS, Allow, pub struct BoxPointers; +impl Copy for BoxPointers {} + impl BoxPointers { fn check_heap_type<'a, 'tcx>(&self, cx: &Context<'a, 'tcx>, span: Span, ty: Ty<'tcx>) { @@ -587,6 +599,8 @@ declare_lint!(UNUSED_ATTRIBUTES, Warn, pub struct UnusedAttributes; +impl Copy for UnusedAttributes {} + impl LintPass for UnusedAttributes { fn get_lints(&self) -> LintArray { lint_array!(UNUSED_ATTRIBUTES) @@ -666,6 +680,8 @@ declare_lint!(pub PATH_STATEMENTS, Warn, pub struct PathStatements; +impl Copy for PathStatements {} + impl LintPass for PathStatements { fn get_lints(&self) -> LintArray { lint_array!(PATH_STATEMENTS) @@ -693,6 +709,8 @@ declare_lint!(pub UNUSED_RESULTS, Allow, pub struct UnusedResults; +impl Copy for UnusedResults {} + impl LintPass for UnusedResults { fn get_lints(&self) -> LintArray { lint_array!(UNUSED_MUST_USE, UNUSED_RESULTS) @@ -757,6 +775,8 @@ declare_lint!(pub NON_CAMEL_CASE_TYPES, Warn, pub struct NonCamelCaseTypes; +impl Copy for NonCamelCaseTypes {} + impl NonCamelCaseTypes { fn check_case(&self, cx: &Context, sort: &str, ident: ast::Ident, span: Span) { fn is_camel_case(ident: ast::Ident) -> bool { @@ -876,6 +896,8 @@ declare_lint!(pub NON_SNAKE_CASE, Warn, pub struct NonSnakeCase; +impl Copy for NonSnakeCase {} + impl NonSnakeCase { fn check_snake_case(&self, cx: &Context, sort: &str, ident: ast::Ident, span: Span) { fn is_snake_case(ident: ast::Ident) -> bool { @@ -985,6 +1007,8 @@ declare_lint!(pub NON_UPPER_CASE_GLOBALS, Warn, pub struct NonUpperCaseGlobals; +impl Copy for NonUpperCaseGlobals {} + impl LintPass for NonUpperCaseGlobals { fn get_lints(&self) -> LintArray { lint_array!(NON_UPPER_CASE_GLOBALS) @@ -1034,6 +1058,8 @@ declare_lint!(UNUSED_PARENS, Warn, pub struct UnusedParens; +impl Copy for UnusedParens {} + impl UnusedParens { fn check_unused_parens_core(&self, cx: &Context, value: &ast::Expr, msg: &str, struct_lit_needs_parens: bool) { @@ -1124,6 +1150,8 @@ declare_lint!(UNUSED_IMPORT_BRACES, Allow, pub struct UnusedImportBraces; +impl Copy for UnusedImportBraces {} + impl LintPass for UnusedImportBraces { fn get_lints(&self) -> LintArray { lint_array!(UNUSED_IMPORT_BRACES) @@ -1159,6 +1187,8 @@ declare_lint!(NON_SHORTHAND_FIELD_PATTERNS, Warn, pub struct NonShorthandFieldPatterns; +impl Copy for NonShorthandFieldPatterns {} + impl LintPass for NonShorthandFieldPatterns { fn get_lints(&self) -> LintArray { lint_array!(NON_SHORTHAND_FIELD_PATTERNS) @@ -1188,6 +1218,8 @@ declare_lint!(pub UNUSED_UNSAFE, Warn, pub struct UnusedUnsafe; +impl Copy for UnusedUnsafe {} + impl LintPass for UnusedUnsafe { fn get_lints(&self) -> LintArray { lint_array!(UNUSED_UNSAFE) @@ -1209,6 +1241,8 @@ declare_lint!(UNSAFE_BLOCKS, Allow, pub struct UnsafeBlocks; +impl Copy for UnsafeBlocks {} + impl LintPass for UnsafeBlocks { fn get_lints(&self) -> LintArray { lint_array!(UNSAFE_BLOCKS) @@ -1229,6 +1263,8 @@ declare_lint!(pub UNUSED_MUT, Warn, pub struct UnusedMut; +impl Copy for UnusedMut {} + impl UnusedMut { fn check_unused_mut_pat(&self, cx: &Context, pats: &[P]) { // collect all mutable pattern and group their NodeIDs by their Identifier to @@ -1294,6 +1330,8 @@ declare_lint!(UNUSED_ALLOCATION, Warn, pub struct UnusedAllocation; +impl Copy for UnusedAllocation {} + impl LintPass for UnusedAllocation { fn get_lints(&self) -> LintArray { lint_array!(UNUSED_ALLOCATION) @@ -1479,6 +1517,61 @@ impl LintPass for MissingDoc { } } +pub struct MissingCopyImplementations; + +impl Copy for MissingCopyImplementations {} + +impl LintPass for MissingCopyImplementations { + fn get_lints(&self) -> LintArray { + lint_array!(MISSING_COPY_IMPLEMENTATIONS) + } + + fn check_item(&mut self, cx: &Context, item: &ast::Item) { + if !cx.exported_items.contains(&item.id) { + return + } + if cx.tcx + .destructor_for_type + .borrow() + .contains_key(&ast_util::local_def(item.id)) { + return + } + let ty = match item.node { + ast::ItemStruct(_, ref ast_generics) => { + if ast_generics.is_parameterized() { + return + } + ty::mk_struct(cx.tcx, + ast_util::local_def(item.id), + Substs::empty()) + } + ast::ItemEnum(_, ref ast_generics) => { + if ast_generics.is_parameterized() { + return + } + ty::mk_enum(cx.tcx, + ast_util::local_def(item.id), + Substs::empty()) + } + _ => return, + }; + let parameter_environment = ty::empty_parameter_environment(); + if !ty::type_moves_by_default(cx.tcx, + ty, + ¶meter_environment) { + return + } + if ty::can_type_implement_copy(cx.tcx, + ty, + ¶meter_environment).is_ok() { + cx.span_lint(MISSING_COPY_IMPLEMENTATIONS, + item.span, + "type could implement `Copy`; consider adding `impl \ + Copy`") + } + } +} + declare_lint!(DEPRECATED, Warn, "detects use of #[deprecated] items") @@ -1493,6 +1586,8 @@ declare_lint!(UNSTABLE, Allow, /// `#[unstable]` attributes, or no stability attribute. pub struct Stability; +impl Copy for Stability {} + impl Stability { fn lint(&self, cx: &Context, id: ast::DefId, span: Span) { let stability = stability::lookup(cx.tcx, id); @@ -1682,10 +1777,15 @@ declare_lint!(pub VARIANT_SIZE_DIFFERENCES, Allow, declare_lint!(pub FAT_PTR_TRANSMUTES, Allow, "detects transmutes of fat pointers") +declare_lint!(pub MISSING_COPY_IMPLEMENTATIONS, Warn, + "detects potentially-forgotten implementations of `Copy`") + /// Does nothing as a lint pass, but registers some `Lint`s /// which are used by other parts of the compiler. pub struct HardwiredLints; +impl Copy for HardwiredLints {} + impl LintPass for HardwiredLints { fn get_lints(&self) -> LintArray { lint_array!( diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 442d3aab92d..153a00e5617 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -204,6 +204,7 @@ impl LintStore { UnusedMut, UnusedAllocation, Stability, + MissingCopyImplementations, ) add_builtin_with_new!(sess, diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index d6b83752cc5..4b4ba2ab94c 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -64,6 +64,8 @@ pub struct Lint { pub desc: &'static str, } +impl Copy for Lint {} + impl Lint { /// Get the lint's name, with ASCII letters converted to lowercase. pub fn name_lower(&self) -> String { @@ -179,6 +181,8 @@ pub struct LintId { lint: &'static Lint, } +impl Copy for LintId {} + impl PartialEq for LintId { fn eq(&self, other: &LintId) -> bool { (self.lint as *const Lint) == (other.lint as *const Lint) @@ -214,6 +218,8 @@ pub enum Level { Allow, Warn, Deny, Forbid } +impl Copy for Level {} + impl Level { /// Convert a level to a lower-case string. pub fn as_str(self) -> &'static str { @@ -251,6 +257,8 @@ pub enum LintSource { CommandLine, } +impl Copy for LintSource {} + pub type LevelSource = (Level, LintSource); pub mod builtin; diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index 0da3b1b7a4e..315e0eea9b7 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -144,6 +144,8 @@ pub enum astencode_tag { // Reserves 0x40 -- 0x5f tag_table_capture_modes = 0x56, tag_table_object_cast_map = 0x57, } + +impl Copy for astencode_tag {} static first_astencode_tag: uint = tag_ast as uint; static last_astencode_tag: uint = tag_table_object_cast_map as uint; impl astencode_tag { diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index deeab18de7c..9e87153e64a 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -275,8 +275,10 @@ fn visit_item(e: &Env, i: &ast::Item) { } } -fn register_native_lib(sess: &Session, span: Option, name: String, - kind: cstore::NativeLibaryKind) { +fn register_native_lib(sess: &Session, + span: Option, + name: String, + kind: cstore::NativeLibraryKind) { if name.is_empty() { match span { Some(span) => { diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index ebf5cca6a31..b864dc39603 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -40,6 +40,8 @@ pub struct MethodInfo { pub vis: ast::Visibility, } +impl Copy for MethodInfo {} + pub fn get_symbol(cstore: &cstore::CStore, def: ast::DefId) -> String { let cdata = cstore.get_crate_data(def.krate); decoder::get_symbol(cdata.data(), def.node) @@ -273,9 +275,8 @@ pub fn get_impl_vtables<'tcx>(tcx: &ty::ctxt<'tcx>, decoder::get_impl_vtables(&*cdata, def.node, tcx) } -pub fn get_native_libraries(cstore: &cstore::CStore, - crate_num: ast::CrateNum) - -> Vec<(cstore::NativeLibaryKind, String)> { +pub fn get_native_libraries(cstore: &cstore::CStore, crate_num: ast::CrateNum) + -> Vec<(cstore::NativeLibraryKind, String)> { let cdata = cstore.get_crate_data(crate_num); decoder::get_native_libraries(&*cdata) } diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index f93a1699e18..91f360a7a38 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -15,7 +15,7 @@ pub use self::MetadataBlob::*; pub use self::LinkagePreference::*; -pub use self::NativeLibaryKind::*; +pub use self::NativeLibraryKind::*; use back::svh::Svh; use metadata::decoder; @@ -54,13 +54,17 @@ pub enum LinkagePreference { RequireStatic, } -#[deriving(PartialEq, FromPrimitive, Clone)] -pub enum NativeLibaryKind { +impl Copy for LinkagePreference {} + +#[deriving(Clone, PartialEq, FromPrimitive)] +pub enum NativeLibraryKind { NativeStatic, // native static library (.a archive) NativeFramework, // OSX-specific NativeUnknown, // default way to specify a dynamic library } +impl Copy for NativeLibraryKind {} + // Where a crate came from on the local filesystem. One of these two options // must be non-None. #[deriving(PartialEq, Clone)] @@ -75,7 +79,7 @@ pub struct CStore { /// Map from NodeId's of local extern crate statements to crate numbers extern_mod_crate_map: RefCell>, used_crate_sources: RefCell>, - used_libraries: RefCell>, + used_libraries: RefCell>, used_link_args: RefCell>, pub intr: Rc, } @@ -186,13 +190,14 @@ impl CStore { libs } - pub fn add_used_library(&self, lib: String, kind: NativeLibaryKind) { + pub fn add_used_library(&self, lib: String, kind: NativeLibraryKind) { assert!(!lib.is_empty()); self.used_libraries.borrow_mut().push((lib, kind)); } pub fn get_used_libraries<'a>(&'a self) - -> &'a RefCell > { + -> &'a RefCell> { &self.used_libraries } diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index f352a28df69..0d51e044de9 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -442,6 +442,8 @@ pub enum DefLike { DlField } +impl Copy for DefLike {} + /// Iterates over the language items in the given crate. pub fn each_lang_item(cdata: Cmd, f: |ast::NodeId, uint| -> bool) -> bool { let root = rbml::Doc::new(cdata.data()); @@ -1267,14 +1269,14 @@ pub fn get_trait_of_item(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt) pub fn get_native_libraries(cdata: Cmd) - -> Vec<(cstore::NativeLibaryKind, String)> { + -> Vec<(cstore::NativeLibraryKind, String)> { let libraries = reader::get_doc(rbml::Doc::new(cdata.data()), tag_native_libraries); let mut result = Vec::new(); reader::tagged_docs(libraries, tag_native_libraries_lib, |lib_doc| { let kind_doc = reader::get_doc(lib_doc, tag_native_libraries_kind); let name_doc = reader::get_doc(lib_doc, tag_native_libraries_name); - let kind: cstore::NativeLibaryKind = + let kind: cstore::NativeLibraryKind = FromPrimitive::from_u32(reader::doc_as_u32(kind_doc)).unwrap(); let name = name_doc.as_str().to_string(); result.push((kind, name)); diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index 63fc2af492c..2d23a61813a 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -20,7 +20,12 @@ use std::os; use util::fs as myfs; -pub enum FileMatch { FileMatches, FileDoesntMatch } +pub enum FileMatch { + FileMatches, + FileDoesntMatch, +} + +impl Copy for FileMatch {} // A module for searching for libraries // FIXME (#2658): I'm not happy how this module turned out. Should diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 00d12ad6a38..e29741fb4a1 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -61,6 +61,8 @@ pub enum DefIdSource { // Identifies an unboxed closure UnboxedClosureSource } + +impl Copy for DefIdSource {} pub type conv_did<'a> = |source: DefIdSource, ast::DefId|: 'a -> ast::DefId; diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index 72c6256dcb5..5f030324d42 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -24,7 +24,9 @@ use middle::borrowck::LoanPathKind::*; use middle::expr_use_visitor as euv; use middle::mem_categorization as mc; use middle::region; +use middle::ty::ParameterEnvironment; use middle::ty; +use syntax::ast::NodeId; use syntax::ast; use syntax::codemap::Span; use util::ppaux::Repr; @@ -89,6 +91,7 @@ struct CheckLoanCtxt<'a, 'tcx: 'a> { dfcx_loans: &'a LoanDataFlow<'a, 'tcx>, move_data: move_data::FlowedMoveData<'a, 'tcx>, all_loans: &'a [Loan<'tcx>], + param_env: &'a ParameterEnvironment<'tcx>, } impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> { @@ -193,19 +196,25 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, dfcx_loans: &LoanDataFlow<'b, 'tcx>, move_data: move_data::FlowedMoveData<'c, 'tcx>, all_loans: &[Loan<'tcx>], + fn_id: NodeId, decl: &ast::FnDecl, body: &ast::Block) { debug!("check_loans(body id={})", body.id); + let param_env = ParameterEnvironment::for_item(bccx.tcx, fn_id); + let mut clcx = CheckLoanCtxt { bccx: bccx, dfcx_loans: dfcx_loans, move_data: move_data, all_loans: all_loans, + param_env: ¶m_env, }; { - let mut euv = euv::ExprUseVisitor::new(&mut clcx, bccx.tcx); + let mut euv = euv::ExprUseVisitor::new(&mut clcx, + bccx.tcx, + param_env.clone()); euv.walk_fn(decl, body); } } @@ -700,7 +709,8 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { use_kind, &**lp, the_move, - moved_lp); + moved_lp, + self.param_env); false }); } diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs index edffe59fff5..ca9d4b512b3 100644 --- a/src/librustc/middle/borrowck/gather_loans/mod.rs +++ b/src/librustc/middle/borrowck/gather_loans/mod.rs @@ -22,6 +22,7 @@ use middle::borrowck::move_data::MoveData; use middle::expr_use_visitor as euv; use middle::mem_categorization as mc; use middle::region; +use middle::ty::ParameterEnvironment; use middle::ty; use util::ppaux::{Repr}; @@ -37,10 +38,11 @@ mod gather_moves; mod move_error; pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, + fn_id: NodeId, decl: &ast::FnDecl, body: &ast::Block) - -> (Vec>, move_data::MoveData<'tcx>) -{ + -> (Vec>, + move_data::MoveData<'tcx>) { let mut glcx = GatherLoanCtxt { bccx: bccx, all_loans: Vec::new(), @@ -49,8 +51,12 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, move_error_collector: move_error::MoveErrorCollector::new(), }; + let param_env = ParameterEnvironment::for_item(bccx.tcx, fn_id); + { - let mut euv = euv::ExprUseVisitor::new(&mut glcx, bccx.tcx); + let mut euv = euv::ExprUseVisitor::new(&mut glcx, + bccx.tcx, + param_env); euv.walk_fn(decl, body); } diff --git a/src/librustc/middle/borrowck/graphviz.rs b/src/librustc/middle/borrowck/graphviz.rs index a209b1a28f2..32fa5f8c3a9 100644 --- a/src/librustc/middle/borrowck/graphviz.rs +++ b/src/librustc/middle/borrowck/graphviz.rs @@ -34,6 +34,8 @@ pub enum Variant { Assigns, } +impl Copy for Variant {} + impl Variant { pub fn short_name(&self) -> &'static str { match *self { diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index 0bbcdfe61bb..e90de1b6912 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -25,7 +25,7 @@ use middle::dataflow::DataFlowOperator; use middle::expr_use_visitor as euv; use middle::mem_categorization as mc; use middle::region; -use middle::ty::{mod, Ty}; +use middle::ty::{mod, ParameterEnvironment, Ty}; use util::ppaux::{note_and_explain_region, Repr, UserString}; use std::rc::Rc; @@ -62,6 +62,8 @@ pub mod move_data; #[deriving(Clone)] pub struct LoanDataFlowOperator; +impl Copy for LoanDataFlowOperator {} + pub type LoanDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, LoanDataFlowOperator>; impl<'a, 'tcx, 'v> Visitor<'v> for BorrowckCtxt<'a, 'tcx> { @@ -146,8 +148,13 @@ fn borrowck_fn(this: &mut BorrowckCtxt, move_data::fragments::instrument_move_fragments(&flowed_moves.move_data, this.tcx, sp, id); - check_loans::check_loans(this, &loan_dfcx, flowed_moves, - all_loans.as_slice(), decl, body); + check_loans::check_loans(this, + &loan_dfcx, + flowed_moves, + all_loans.as_slice(), + id, + decl, + body); visit::walk_fn(this, fk, decl, body, sp); } @@ -162,7 +169,7 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>, // Check the body of fn items. let id_range = ast_util::compute_id_range_for_fn_body(fk, decl, body, sp, id); let (all_loans, move_data) = - gather_loans::gather_loans_in_fn(this, decl, body); + gather_loans::gather_loans_in_fn(this, id, decl, body); let mut loan_dfcx = DataFlowContext::new(this.tcx, @@ -339,6 +346,8 @@ pub enum LoanPathElem { LpInterior(mc::InteriorKind) // `LV.f` in doc.rs } +impl Copy for LoanPathElem {} + pub fn closure_to_block(closure_id: ast::NodeId, tcx: &ty::ctxt) -> ast::NodeId { match tcx.map.get(closure_id) { @@ -484,6 +493,7 @@ pub fn opt_loan_path<'tcx>(cmt: &mc::cmt<'tcx>) -> Option>> { // Errors that can occur #[deriving(PartialEq)] +#[allow(missing_copy_implementations)] pub enum bckerr_code { err_mutbl, err_out_of_scope(ty::Region, ty::Region), // superscope, subscope @@ -505,12 +515,16 @@ pub enum AliasableViolationKind { BorrowViolation(euv::LoanCause) } +impl Copy for AliasableViolationKind {} + #[deriving(Show)] pub enum MovedValueUseKind { MovedInUse, MovedInCapture, } +impl Copy for MovedValueUseKind {} + /////////////////////////////////////////////////////////////////////////// // Misc @@ -545,7 +559,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { use_kind: MovedValueUseKind, lp: &LoanPath<'tcx>, the_move: &move_data::Move, - moved_lp: &LoanPath<'tcx>) { + moved_lp: &LoanPath<'tcx>, + param_env: &ParameterEnvironment<'tcx>) { let verb = match use_kind { MovedInUse => "use", MovedInCapture => "capture", @@ -621,7 +636,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { r).as_slice()) } }; - let (suggestion, _) = move_suggestion(self.tcx, expr_ty, + let (suggestion, _) = move_suggestion(self.tcx, param_env, expr_ty, ("moved by default", "")); self.tcx.sess.span_note( expr_span, @@ -659,7 +674,9 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { r).as_slice()) } }; - let (suggestion, help) = move_suggestion(self.tcx, expr_ty, + let (suggestion, help) = move_suggestion(self.tcx, + param_env, + expr_ty, ("moved by default", "make a copy and \ capture that instead to override")); self.tcx.sess.span_note( @@ -674,7 +691,9 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } } - fn move_suggestion<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>, + fn move_suggestion<'tcx>(tcx: &ty::ctxt<'tcx>, + param_env: &ty::ParameterEnvironment<'tcx>, + ty: Ty<'tcx>, default_msgs: (&'static str, &'static str)) -> (&'static str, &'static str) { match ty.sty { @@ -684,7 +703,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { }) => ("a non-copyable stack closure", "capture it in a new closure, e.g. `|x| f(x)`, to override"), - _ if ty::type_moves_by_default(tcx, ty) => + _ if ty::type_moves_by_default(tcx, ty, param_env) => ("non-copyable", "perhaps you meant to use `clone()`?"), _ => default_msgs, diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs index 7bf3458f0ae..3bb6145c5ca 100644 --- a/src/librustc/middle/borrowck/move_data.rs +++ b/src/librustc/middle/borrowck/move_data.rs @@ -81,6 +81,8 @@ pub struct FlowedMoveData<'a, 'tcx: 'a> { #[deriving(PartialEq, Eq, PartialOrd, Ord, Show)] pub struct MovePathIndex(uint); +impl Copy for MovePathIndex {} + impl MovePathIndex { fn get(&self) -> uint { let MovePathIndex(v) = *self; v @@ -101,6 +103,8 @@ static InvalidMovePathIndex: MovePathIndex = #[deriving(PartialEq)] pub struct MoveIndex(uint); +impl Copy for MoveIndex {} + impl MoveIndex { fn get(&self) -> uint { let MoveIndex(v) = *self; v @@ -138,6 +142,8 @@ pub enum MoveKind { Captured // Closure creation that moves a value } +impl Copy for MoveKind {} + pub struct Move { /// Path being moved. pub path: MovePathIndex, @@ -152,6 +158,8 @@ pub struct Move { pub next_move: MoveIndex } +impl Copy for Move {} + pub struct Assignment { /// Path being assigned. pub path: MovePathIndex, @@ -163,6 +171,8 @@ pub struct Assignment { pub span: Span, } +impl Copy for Assignment {} + pub struct VariantMatch { /// downcast to the variant. pub path: MovePathIndex, @@ -177,14 +187,20 @@ pub struct VariantMatch { pub mode: euv::MatchMode } +impl Copy for VariantMatch {} + #[deriving(Clone)] pub struct MoveDataFlowOperator; +impl Copy for MoveDataFlowOperator {} + pub type MoveDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, MoveDataFlowOperator>; #[deriving(Clone)] pub struct AssignDataFlowOperator; +impl Copy for AssignDataFlowOperator {} + pub type AssignDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, AssignDataFlowOperator>; fn loan_path_is_precise(loan_path: &LoanPath) -> bool { diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index 90919609e2e..0dcb78f6bb0 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -32,6 +32,8 @@ struct LoopScope { break_index: CFGIndex, // where to go on a `break } +impl Copy for LoopScope {} + pub fn construct(tcx: &ty::ctxt, blk: &ast::Block) -> CFG { let mut graph = graph::Graph::new(); diff --git a/src/librustc/middle/cfg/mod.rs b/src/librustc/middle/cfg/mod.rs index a2e8ba8d65c..bc512a73a4b 100644 --- a/src/librustc/middle/cfg/mod.rs +++ b/src/librustc/middle/cfg/mod.rs @@ -30,6 +30,8 @@ pub struct CFGNodeData { pub id: ast::NodeId } +impl Copy for CFGNodeData {} + pub struct CFGEdgeData { pub exiting_scopes: Vec } diff --git a/src/librustc/middle/check_loop.rs b/src/librustc/middle/check_loop.rs index 36742df9850..eb073e07b02 100644 --- a/src/librustc/middle/check_loop.rs +++ b/src/librustc/middle/check_loop.rs @@ -21,11 +21,15 @@ enum Context { Normal, Loop, Closure } +impl Copy for Context {} + struct CheckLoopVisitor<'a> { sess: &'a Session, cx: Context } +impl<'a> Copy for CheckLoopVisitor<'a> {} + pub fn check_crate(sess: &Session, krate: &ast::Crate) { visit::walk_crate(&mut CheckLoopVisitor { sess: sess, cx: Normal }, krate) } diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index ed119081f78..2c437ae046b 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -99,7 +99,8 @@ impl<'a> FromIterator> for Matrix<'a> { } pub struct MatchCheckCtxt<'a, 'tcx: 'a> { - pub tcx: &'a ty::ctxt<'tcx> + pub tcx: &'a ty::ctxt<'tcx>, + pub param_env: ParameterEnvironment<'tcx>, } #[deriving(Clone, PartialEq)] @@ -131,6 +132,8 @@ enum WitnessPreference { LeaveOutWitness } +impl Copy for WitnessPreference {} + impl<'a, 'tcx, 'v> Visitor<'v> for MatchCheckCtxt<'a, 'tcx> { fn visit_expr(&mut self, ex: &ast::Expr) { check_expr(self, ex); @@ -145,7 +148,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MatchCheckCtxt<'a, 'tcx> { } pub fn check_crate(tcx: &ty::ctxt) { - visit::walk_crate(&mut MatchCheckCtxt { tcx: tcx }, tcx.map.krate()); + visit::walk_crate(&mut MatchCheckCtxt { + tcx: tcx, + param_env: ty::empty_parameter_environment(), + }, tcx.map.krate()); tcx.sess.abort_if_errors(); } @@ -954,8 +960,14 @@ fn check_fn(cx: &mut MatchCheckCtxt, decl: &ast::FnDecl, body: &ast::Block, sp: Span, - _: NodeId) { + fn_id: NodeId) { + match kind { + visit::FkFnBlock => {} + _ => cx.param_env = ParameterEnvironment::for_item(cx.tcx, fn_id), + } + visit::walk_fn(cx, kind, decl, body, sp); + for input in decl.inputs.iter() { is_refutable(cx, &*input.pat, |pat| { span_err!(cx.tcx.sess, input.pat.span, E0006, @@ -1020,7 +1032,9 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt, match p.node { ast::PatIdent(ast::BindByValue(_), _, ref sub) => { let pat_ty = ty::node_id_to_type(tcx, p.id); - if ty::type_moves_by_default(tcx, pat_ty) { + if ty::type_moves_by_default(tcx, + pat_ty, + &cx.param_env) { check_move(p, sub.as_ref().map(|p| &**p)); } } @@ -1048,7 +1062,9 @@ fn check_for_mutation_in_guard<'a, 'tcx>(cx: &'a MatchCheckCtxt<'a, 'tcx>, let mut checker = MutationChecker { cx: cx, }; - let mut visitor = ExprUseVisitor::new(&mut checker, checker.cx.tcx); + let mut visitor = ExprUseVisitor::new(&mut checker, + checker.cx.tcx, + cx.param_env.clone()); visitor.walk_expr(guard); } diff --git a/src/librustc/middle/check_rvalues.rs b/src/librustc/middle/check_rvalues.rs index dae76ba125e..a14307b90ee 100644 --- a/src/librustc/middle/check_rvalues.rs +++ b/src/librustc/middle/check_rvalues.rs @@ -13,6 +13,7 @@ use middle::expr_use_visitor as euv; use middle::mem_categorization as mc; +use middle::ty::ParameterEnvironment; use middle::ty; use util::ppaux::ty_to_string; @@ -36,9 +37,10 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for RvalueContext<'a, 'tcx> { fd: &'v ast::FnDecl, b: &'v ast::Block, s: Span, - _: ast::NodeId) { + fn_id: ast::NodeId) { { - let mut euv = euv::ExprUseVisitor::new(self, self.tcx); + let param_env = ParameterEnvironment::for_item(self.tcx, fn_id); + let mut euv = euv::ExprUseVisitor::new(self, self.tcx, param_env); euv.walk_fn(fd, b); } visit::walk_fn(self, fk, fd, b, s) diff --git a/src/librustc/middle/check_static.rs b/src/librustc/middle/check_static.rs index 2fc85afd393..a495d1e049d 100644 --- a/src/librustc/middle/check_static.rs +++ b/src/librustc/middle/check_static.rs @@ -47,13 +47,16 @@ enum Mode { InNothing, } +impl Copy for Mode {} + struct CheckStaticVisitor<'a, 'tcx: 'a> { tcx: &'a ty::ctxt<'tcx>, mode: Mode, checker: &'a mut GlobalChecker, } -struct GlobalVisitor<'a, 'b, 'tcx: 'b>(euv::ExprUseVisitor<'a, 'b, 'tcx, ty::ctxt<'tcx>>); +struct GlobalVisitor<'a,'b,'tcx:'a+'b>( + euv::ExprUseVisitor<'a,'b,'tcx,ty::ctxt<'tcx>>); struct GlobalChecker { static_consumptions: NodeSet, const_borrows: NodeSet, @@ -69,7 +72,8 @@ pub fn check_crate(tcx: &ty::ctxt) { static_local_borrows: NodeSet::new(), }; { - let visitor = euv::ExprUseVisitor::new(&mut checker, tcx); + let param_env = ty::empty_parameter_environment(); + let visitor = euv::ExprUseVisitor::new(&mut checker, tcx, param_env); visit::walk_crate(&mut GlobalVisitor(visitor), tcx.map.krate()); } visit::walk_crate(&mut CheckStaticVisitor { @@ -242,7 +246,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckStaticVisitor<'a, 'tcx> { } } -impl<'a, 'b, 't, 'v> Visitor<'v> for GlobalVisitor<'a, 'b, 't> { +impl<'a,'b,'t,'v> Visitor<'v> for GlobalVisitor<'a,'b,'t> { fn visit_item(&mut self, item: &ast::Item) { match item.node { ast::ItemConst(_, ref e) | diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 43726f55bb9..150bcbdd688 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -68,6 +68,8 @@ pub enum constness { non_const } +impl Copy for constness {} + type constness_cache = DefIdMap; pub fn join(a: constness, b: constness) -> constness { diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index 53fea8ffc86..db8fd999f38 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -28,7 +28,12 @@ use syntax::print::{pp, pprust}; use util::nodemap::NodeMap; #[deriving(Show)] -pub enum EntryOrExit { Entry, Exit } +pub enum EntryOrExit { + Entry, + Exit, +} + +impl Copy for EntryOrExit {} #[deriving(Clone)] pub struct DataFlowContext<'a, 'tcx: 'a, O> { diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs index 4a4298f62f2..b3e4dd25adc 100644 --- a/src/librustc/middle/def.rs +++ b/src/librustc/middle/def.rs @@ -52,6 +52,8 @@ pub enum Def { DefMethod(ast::DefId /* method */, Option /* trait */, MethodProvenance), } +impl Copy for Def {} + #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum MethodProvenance { FromTrait(ast::DefId), @@ -67,6 +69,8 @@ impl MethodProvenance { } } +impl Copy for MethodProvenance {} + impl Def { pub fn def_id(&self) -> ast::DefId { match *self { diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index dbec69f4205..8bf43c70c26 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -30,6 +30,8 @@ enum UnsafeContext { UnsafeBlock(ast::NodeId), } +impl Copy for UnsafeContext {} + fn type_is_unsafe_function(ty: Ty) -> bool { match ty.sty { ty::ty_bare_fn(ref f) => f.fn_style == ast::UnsafeFn, diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 7d2bb7458ac..8e00c96535b 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -23,12 +23,13 @@ use self::OverloadedCallType::*; use middle::{def, region, pat_util}; use middle::mem_categorization as mc; use middle::mem_categorization::Typer; -use middle::ty::{mod, Ty}; +use middle::ty::{mod, ParameterEnvironment, Ty}; use middle::ty::{MethodCall, MethodObject, MethodTraitObject}; use middle::ty::{MethodOrigin, MethodParam, MethodTypeParam}; use middle::ty::{MethodStatic, MethodStaticUnboxedClosure}; use util::ppaux::Repr; +use std::kinds; use syntax::ast; use syntax::ptr::P; use syntax::codemap::Span; @@ -106,12 +107,16 @@ pub enum LoanCause { MatchDiscriminant } +impl kinds::Copy for LoanCause {} + #[deriving(PartialEq, Show)] pub enum ConsumeMode { Copy, // reference to x where x has a type that copies Move(MoveReason), // reference to x where x has a type that moves } +impl kinds::Copy for ConsumeMode {} + #[deriving(PartialEq,Show)] pub enum MoveReason { DirectRefMove, @@ -119,6 +124,8 @@ pub enum MoveReason { CaptureMove, } +impl kinds::Copy for MoveReason {} + #[deriving(PartialEq,Show)] pub enum MatchMode { NonBindingMatch, @@ -127,11 +134,17 @@ pub enum MatchMode { MovingMatch, } +impl kinds::Copy for MatchMode {} + #[deriving(PartialEq,Show)] enum TrackMatchMode { - Unknown, Definite(MatchMode), Conflicting, + Unknown, + Definite(MatchMode), + Conflicting, } +impl kinds::Copy for TrackMatchMode {} + impl TrackMatchMode { // Builds up the whole match mode for a pattern from its constituent // parts. The lattice looks like this: @@ -199,12 +212,16 @@ pub enum MutateMode { WriteAndRead, // x += y } +impl kinds::Copy for MutateMode {} + enum OverloadedCallType { FnOverloadedCall, FnMutOverloadedCall, FnOnceOverloadedCall, } +impl kinds::Copy for OverloadedCallType {} + impl OverloadedCallType { fn from_trait_id(tcx: &ty::ctxt, trait_id: ast::DefId) -> OverloadedCallType { @@ -293,6 +310,7 @@ pub struct ExprUseVisitor<'d,'t,'tcx,TYPER:'t> { typer: &'t TYPER, mc: mc::MemCategorizationContext<'t,TYPER>, delegate: &'d mut (Delegate<'tcx>+'d), + param_env: ParameterEnvironment<'tcx>, } // If the TYPER results in an error, it's because the type check @@ -313,11 +331,15 @@ macro_rules! return_if_err( impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { pub fn new(delegate: &'d mut Delegate<'tcx>, - typer: &'t TYPER) + typer: &'t TYPER, + param_env: ParameterEnvironment<'tcx>) -> ExprUseVisitor<'d,'t,'tcx,TYPER> { - ExprUseVisitor { typer: typer, - mc: mc::MemCategorizationContext::new(typer), - delegate: delegate } + ExprUseVisitor { + typer: typer, + mc: mc::MemCategorizationContext::new(typer), + delegate: delegate, + param_env: param_env, + } } pub fn walk_fn(&mut self, @@ -352,7 +374,10 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { consume_id: ast::NodeId, consume_span: Span, cmt: mc::cmt<'tcx>) { - let mode = copy_or_move(self.tcx(), cmt.ty, DirectRefMove); + let mode = copy_or_move(self.tcx(), + cmt.ty, + &self.param_env, + DirectRefMove); self.delegate.consume(consume_id, consume_span, cmt, mode); } @@ -954,7 +979,10 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { ast::PatIdent(ast::BindByRef(_), _, _) => mode.lub(BorrowingMatch), ast::PatIdent(ast::BindByValue(_), _, _) => { - match copy_or_move(tcx, cmt_pat.ty, PatBindingMove) { + match copy_or_move(tcx, + cmt_pat.ty, + &self.param_env, + PatBindingMove) { Copy => mode.lub(CopyingMatch), Move(_) => mode.lub(MovingMatch), } @@ -984,7 +1012,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { let tcx = typer.tcx(); let def_map = &self.typer.tcx().def_map; let delegate = &mut self.delegate; - + let param_env = &mut self.param_env; return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |mc, cmt_pat, pat| { if pat_util::pat_is_binding(def_map, pat) { let tcx = typer.tcx(); @@ -1018,7 +1046,10 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { r, bk, RefBinding); } ast::PatIdent(ast::BindByValue(_), _, _) => { - let mode = copy_or_move(typer.tcx(), cmt_pat.ty, PatBindingMove); + let mode = copy_or_move(typer.tcx(), + cmt_pat.ty, + param_env, + PatBindingMove); debug!("walk_pat binding consuming pat"); delegate.consume_pat(pat, cmt_pat, mode); } @@ -1211,7 +1242,10 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id, closure_expr.span, freevar.def)); - let mode = copy_or_move(self.tcx(), cmt_var.ty, CaptureMove); + let mode = copy_or_move(self.tcx(), + cmt_var.ty, + &self.param_env, + CaptureMove); self.delegate.consume(closure_expr.id, freevar.span, cmt_var, mode); } } @@ -1229,8 +1263,15 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { } } -fn copy_or_move<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>, - move_reason: MoveReason) -> ConsumeMode { - if ty::type_moves_by_default(tcx, ty) { Move(move_reason) } else { Copy } +fn copy_or_move<'tcx>(tcx: &ty::ctxt<'tcx>, + ty: Ty<'tcx>, + param_env: &ParameterEnvironment<'tcx>, + move_reason: MoveReason) + -> ConsumeMode { + if ty::type_moves_by_default(tcx, ty, param_env) { + Move(move_reason) + } else { + Copy + } } diff --git a/src/librustc/middle/fast_reject.rs b/src/librustc/middle/fast_reject.rs index 888f01f9118..6780177933f 100644 --- a/src/librustc/middle/fast_reject.rs +++ b/src/librustc/middle/fast_reject.rs @@ -33,6 +33,8 @@ pub enum SimplifiedType { ParameterSimplifiedType, } +impl Copy for SimplifiedType {} + /// Tries to simplify a type by dropping type parameters, deref'ing away any reference types, etc. /// The idea is to get something simple that we can use to quickly decide if two types could unify /// during method lookup. diff --git a/src/librustc/middle/graph.rs b/src/librustc/middle/graph.rs index 2f50a964023..e45232a3c30 100644 --- a/src/librustc/middle/graph.rs +++ b/src/librustc/middle/graph.rs @@ -65,11 +65,15 @@ pub struct NodeIndex(pub uint); #[allow(non_upper_case_globals)] pub const InvalidNodeIndex: NodeIndex = NodeIndex(uint::MAX); +impl Copy for NodeIndex {} + #[deriving(PartialEq, Show)] pub struct EdgeIndex(pub uint); #[allow(non_upper_case_globals)] pub const InvalidEdgeIndex: EdgeIndex = EdgeIndex(uint::MAX); +impl Copy for EdgeIndex {} + // Use a private field here to guarantee no more instances are created: #[deriving(Show)] pub struct Direction { repr: uint } @@ -78,6 +82,8 @@ pub const Outgoing: Direction = Direction { repr: 0 }; #[allow(non_upper_case_globals)] pub const Incoming: Direction = Direction { repr: 1 }; +impl Copy for Direction {} + impl NodeIndex { fn get(&self) -> uint { let NodeIndex(v) = *self; v } /// Returns unique id (unique with respect to the graph holding associated node). diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index c5845b143af..81cd8dd20d2 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -132,6 +132,8 @@ pub enum TypeOrigin { IfExpressionWithNoElse(Span) } +impl Copy for TypeOrigin {} + /// See `error_reporting.rs` for more details #[deriving(Clone, Show)] pub enum ValuePairs<'tcx> { @@ -237,6 +239,8 @@ pub enum LateBoundRegionConversionTime { HigherRankedType, } +impl Copy for LateBoundRegionConversionTime {} + /// Reasons to create a region inference variable /// /// See `error_reporting.rs` for more details @@ -280,6 +284,8 @@ pub enum fixup_err { unresolved_ty(TyVid) } +impl Copy for fixup_err {} + pub fn fixup_err_to_string(f: fixup_err) -> String { match f { unresolved_int_ty(_) => { diff --git a/src/librustc/middle/infer/region_inference/mod.rs b/src/librustc/middle/infer/region_inference/mod.rs index 9155c18cb3b..391e37e8b9c 100644 --- a/src/librustc/middle/infer/region_inference/mod.rs +++ b/src/librustc/middle/infer/region_inference/mod.rs @@ -51,6 +51,8 @@ pub enum Constraint { ConstrainVarSubReg(RegionVid, Region), } +impl Copy for Constraint {} + // Something we have to verify after region inference is done, but // which does not directly influence the inference process pub enum Verify<'tcx> { @@ -72,6 +74,8 @@ pub struct TwoRegions { b: Region, } +impl Copy for TwoRegions {} + #[deriving(PartialEq)] pub enum UndoLogEntry { OpenSnapshot, @@ -84,11 +88,15 @@ pub enum UndoLogEntry { AddCombination(CombineMapType, TwoRegions) } +impl Copy for UndoLogEntry {} + #[deriving(PartialEq)] pub enum CombineMapType { Lub, Glb } +impl Copy for CombineMapType {} + #[deriving(Clone, Show)] pub enum RegionResolutionError<'tcx> { /// `ConcreteFailure(o, a, b)`: @@ -220,11 +228,15 @@ pub struct RegionSnapshot { length: uint } +impl Copy for RegionSnapshot {} + #[deriving(Show)] pub struct RegionMark { length: uint } +impl Copy for RegionMark {} + impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { pub fn new(tcx: &'a ty::ctxt<'tcx>) -> RegionVarBindings<'a, 'tcx> { RegionVarBindings { @@ -926,8 +938,12 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { #[deriving(PartialEq, Show)] enum Classification { Expanding, Contracting } +impl Copy for Classification {} + pub enum VarValue { NoValue, Value(Region), ErrorValue } +impl Copy for VarValue {} + struct VarData { classification: Classification, value: VarValue, diff --git a/src/librustc/middle/infer/type_variable.rs b/src/librustc/middle/infer/type_variable.rs index 3058f09a83a..766e930486c 100644 --- a/src/librustc/middle/infer/type_variable.rs +++ b/src/librustc/middle/infer/type_variable.rs @@ -49,6 +49,8 @@ pub enum RelationDir { SubtypeOf, SupertypeOf, EqTo } +impl Copy for RelationDir {} + impl RelationDir { fn opposite(self) -> RelationDir { match self { diff --git a/src/librustc/middle/infer/unify.rs b/src/librustc/middle/infer/unify.rs index 6f6adb84a75..a2dd4d62913 100644 --- a/src/librustc/middle/infer/unify.rs +++ b/src/librustc/middle/infer/unify.rs @@ -92,6 +92,8 @@ pub struct Node { pub struct Delegate; +impl Copy for Delegate {} + // We can't use V:LatticeValue, much as I would like to, // because frequently the pattern is that V=Option for some // other type parameter U, and we have no way to say diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index da1c0bd649a..4a20c92d8e2 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -50,6 +50,8 @@ pub enum LangItem { $($variant),* } +impl Copy for LangItem {} + pub struct LanguageItems { pub items: Vec>, pub missing: Vec, diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index a6d3c15df8a..5edbafc4e0b 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -137,9 +137,14 @@ enum LoopKind<'a> { #[deriving(PartialEq)] struct Variable(uint); + +impl Copy for Variable {} + #[deriving(PartialEq)] struct LiveNode(uint); +impl Copy for LiveNode {} + impl Variable { fn get(&self) -> uint { let Variable(v) = *self; v } } @@ -162,6 +167,8 @@ enum LiveNodeKind { ExitNode } +impl Copy for LiveNodeKind {} + fn live_node_kind_to_string(lnk: LiveNodeKind, cx: &ty::ctxt) -> String { let cm = cx.sess.codemap(); match lnk { @@ -246,6 +253,8 @@ struct LocalInfo { ident: ast::Ident } +impl Copy for LocalInfo {} + #[deriving(Show)] enum VarKind { Arg(NodeId, ast::Ident), @@ -254,6 +263,8 @@ enum VarKind { CleanExit } +impl Copy for VarKind {} + struct IrMaps<'a, 'tcx: 'a> { tcx: &'a ty::ctxt<'tcx>, @@ -532,6 +543,8 @@ struct Users { used: bool } +impl Copy for Users {} + fn invalid_users() -> Users { Users { reader: invalid_node(), @@ -547,6 +560,8 @@ struct Specials { clean_exit_var: Variable } +impl Copy for Specials {} + static ACC_READ: uint = 1u; static ACC_WRITE: uint = 2u; static ACC_USE: uint = 4u; diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index cd70d8e2b48..302fbd53dd5 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -110,6 +110,8 @@ pub struct Upvar { pub is_unboxed: bool } +impl Copy for Upvar {} + // different kinds of pointers: #[deriving(Clone, PartialEq, Eq, Hash, Show)] pub enum PointerKind { @@ -119,6 +121,8 @@ pub enum PointerKind { UnsafePtr(ast::Mutability) } +impl Copy for PointerKind {} + // We use the term "interior" to mean "something reachable from the // base without a pointer dereference", e.g. a field #[deriving(Clone, PartialEq, Eq, Hash, Show)] @@ -127,18 +131,24 @@ pub enum InteriorKind { InteriorElement(ElementKind), } +impl Copy for InteriorKind {} + #[deriving(Clone, PartialEq, Eq, Hash, Show)] pub enum FieldName { NamedField(ast::Name), PositionalField(uint) } +impl Copy for FieldName {} + #[deriving(Clone, PartialEq, Eq, Hash, Show)] pub enum ElementKind { VecElement, OtherElement, } +impl Copy for ElementKind {} + #[deriving(Clone, PartialEq, Eq, Hash, Show)] pub enum MutabilityCategory { McImmutable, // Immutable. @@ -146,6 +156,8 @@ pub enum MutabilityCategory { McInherited, // Inherited from the fact that owner is mutable. } +impl Copy for MutabilityCategory {} + // A note about the provenance of a `cmt`. This is used for // special-case handling of upvars such as mutability inference. // Upvar categorization can generate a variable number of nested @@ -158,6 +170,8 @@ pub enum Note { NoteNone // Nothing special } +impl Copy for Note {} + // `cmt`: "Category, Mutability, and Type". // // a complete categorization of a value indicating where it originated @@ -191,6 +205,8 @@ pub enum deref_kind { deref_interior(InteriorKind), } +impl Copy for deref_kind {} + // Categorizes a derefable type. Note that we include vectors and strings as // derefable (we model an index as the combination of a deref and then a // pointer adjustment). @@ -261,6 +277,8 @@ pub struct MemCategorizationContext<'t,TYPER:'t> { typer: &'t TYPER } +impl<'t,TYPER:'t> Copy for MemCategorizationContext<'t,TYPER> {} + pub type McResult = Result; /// The `Typer` trait provides the interface for the mem-categorization @@ -1384,6 +1402,8 @@ pub enum InteriorSafety { InteriorSafe } +impl Copy for InteriorSafety {} + pub enum AliasableReason { AliasableBorrowed, AliasableClosure(ast::NodeId), // Aliasable due to capture Fn closure env @@ -1392,6 +1412,8 @@ pub enum AliasableReason { AliasableStaticMut(InteriorSafety), } +impl Copy for AliasableReason {} + impl<'tcx> cmt_<'tcx> { pub fn guarantor(&self) -> cmt<'tcx> { //! Returns `self` after stripping away any owned pointer derefs or diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 2b8dd8df249..370097004e9 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -41,6 +41,8 @@ pub enum CodeExtent { Misc(ast::NodeId) } +impl Copy for CodeExtent {} + impl CodeExtent { /// Creates a scope that represents the dynamic extent associated /// with `node_id`. @@ -120,6 +122,8 @@ pub struct Context { parent: Option, } +impl Copy for Context {} + struct RegionResolutionVisitor<'a> { sess: &'a Session, diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 8c3aa22c5fc..36b87bbd423 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -94,6 +94,8 @@ struct binding_info { binding_mode: BindingMode, } +impl Copy for binding_info {} + // Map from the name in a pattern to its binding mode. type BindingMap = HashMap; @@ -130,12 +132,16 @@ pub enum LastPrivate { type_used: ImportUse}, } +impl Copy for LastPrivate {} + #[deriving(Show)] pub enum PrivateDep { AllPublic, DependsOn(DefId), } +impl Copy for PrivateDep {} + // How an import is used. #[deriving(PartialEq, Show)] pub enum ImportUse { @@ -143,6 +149,8 @@ pub enum ImportUse { Used, // The import is used. } +impl Copy for ImportUse {} + impl LastPrivate { fn or(self, other: LastPrivate) -> LastPrivate { match (self, other) { @@ -159,12 +167,16 @@ enum PatternBindingMode { ArgumentIrrefutableMode, } +impl Copy for PatternBindingMode {} + #[deriving(PartialEq, Eq, Hash, Show)] enum Namespace { TypeNS, ValueNS } +impl Copy for Namespace {} + #[deriving(PartialEq)] enum NamespaceError { NoError, @@ -173,6 +185,8 @@ enum NamespaceError { ValueError } +impl Copy for NamespaceError {} + /// A NamespaceResult represents the result of resolving an import in /// a particular namespace. The result is either definitely-resolved, /// definitely- unresolved, or unknown. @@ -238,6 +252,8 @@ enum ImportDirectiveSubclass { GlobImport } +impl Copy for ImportDirectiveSubclass {} + /// The context that we thread through while building the reduced graph. #[deriving(Clone)] enum ReducedGraphParent { @@ -294,6 +310,8 @@ enum TypeParameters<'a> { RibKind) } +impl<'a> Copy for TypeParameters<'a> {} + // The rib kind controls the translation of local // definitions (`DefLocal`) to upvars (`DefUpvar`). @@ -319,17 +337,23 @@ enum RibKind { ConstantItemRibKind } +impl Copy for RibKind {} + // Methods can be required or provided. RequiredMethod methods only occur in traits. enum MethodSort { RequiredMethod, ProvidedMethod(NodeId) } +impl Copy for MethodSort {} + enum UseLexicalScopeFlag { DontUseLexicalScope, UseLexicalScope } +impl Copy for UseLexicalScopeFlag {} + enum ModulePrefixResult { NoPrefixFound, PrefixFound(Rc, uint) @@ -342,6 +366,8 @@ pub enum TraitItemKind { TypeTraitItemKind, } +impl Copy for TraitItemKind {} + impl TraitItemKind { pub fn from_explicit_self_category(explicit_self_category: ExplicitSelfCategory) @@ -364,12 +390,16 @@ enum NameSearchType { PathSearch, } +impl Copy for NameSearchType {} + enum BareIdentifierPatternResolution { FoundStructOrEnumVariant(Def, LastPrivate), FoundConst(Def, LastPrivate), BareIdentifierPatternUnresolved } +impl Copy for BareIdentifierPatternResolution {} + // Specifies how duplicates should be handled when adding a child item if // another item exists with the same name in some namespace. #[deriving(PartialEq)] @@ -381,6 +411,8 @@ enum DuplicateCheckingMode { OverwriteDuplicates } +impl Copy for DuplicateCheckingMode {} + /// One local scope. struct Rib { bindings: HashMap, @@ -518,6 +550,8 @@ enum ModuleKind { AnonymousModuleKind, } +impl Copy for ModuleKind {} + /// One node in the tree of modules. struct Module { parent_link: ParentLink, @@ -599,6 +633,8 @@ bitflags! { } } +impl Copy for DefModifiers {} + // Records a possibly-private type definition. #[deriving(Clone)] struct TypeNsDef { @@ -616,6 +652,8 @@ struct ValueNsDef { value_span: Option, } +impl Copy for ValueNsDef {} + // Records the definitions (at most one for each namespace) that a name is // bound to. struct NameBindings { @@ -632,6 +670,8 @@ enum TraitReferenceType { TraitQPath, // :: } +impl Copy for TraitReferenceType {} + impl NameBindings { fn new() -> NameBindings { NameBindings { diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index bd8db1d51df..2ba9ba5631d 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -46,6 +46,8 @@ pub enum DefRegion { /* lifetime decl */ ast::NodeId), } +impl Copy for DefRegion {} + // maps the id of each lifetime reference to the lifetime decl // that it corresponds to pub type NamedRegionMap = NodeMap; diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs index 21f57a9d573..bcc762a9640 100644 --- a/src/librustc/middle/subst.rs +++ b/src/librustc/middle/subst.rs @@ -190,6 +190,8 @@ pub enum ParamSpace { FnSpace, // Type parameters attached to a method or fn } +impl Copy for ParamSpace {} + impl ParamSpace { pub fn all() -> [ParamSpace, ..4] { [TypeSpace, SelfSpace, AssocSpace, FnSpace] diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index e12ec44ad87..d410a456dc9 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -60,6 +60,8 @@ pub struct ObligationCause<'tcx> { pub code: ObligationCauseCode<'tcx> } +impl<'tcx> Copy for ObligationCause<'tcx> {} + #[deriving(Clone)] pub enum ObligationCauseCode<'tcx> { /// Not well classified or should be obvious from span. @@ -95,6 +97,8 @@ pub enum ObligationCauseCode<'tcx> { pub type Obligations<'tcx> = subst::VecPerParamSpace>; +impl<'tcx> Copy for ObligationCauseCode<'tcx> {} + pub type Selection<'tcx> = Vtable<'tcx, Obligation<'tcx>>; #[deriving(Clone,Show)] @@ -338,7 +342,7 @@ impl<'tcx, N> Vtable<'tcx, N> { VtableFnPointer(ref sig) => VtableFnPointer((*sig).clone()), VtableUnboxedClosure(d, ref s) => VtableUnboxedClosure(d, s.clone()), VtableParam(ref p) => VtableParam((*p).clone()), - VtableBuiltin(ref i) => VtableBuiltin(i.map_nested(op)), + VtableBuiltin(ref b) => VtableBuiltin(b.map_nested(op)), } } @@ -348,7 +352,7 @@ impl<'tcx, N> Vtable<'tcx, N> { VtableFnPointer(sig) => VtableFnPointer(sig), VtableUnboxedClosure(d, s) => VtableUnboxedClosure(d, s), VtableParam(p) => VtableParam(p), - VtableBuiltin(i) => VtableBuiltin(i.map_move_nested(op)), + VtableBuiltin(no) => VtableBuiltin(no.map_move_nested(op)), } } } diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 0e6a0c19f70..5ad0d17ad13 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -80,6 +80,7 @@ struct ObligationStack<'prev, 'tcx: 'prev> { previous: Option<&'prev ObligationStack<'prev, 'tcx>> } +#[deriving(Clone)] pub struct SelectionCache<'tcx> { hashmap: RefCell>, SelectionResult<'tcx, Candidate<'tcx>>>>, @@ -102,6 +103,8 @@ pub enum MethodMatchedData { CoerciveMethodMatch(/* impl we matched */ ast::DefId) } +impl Copy for MethodMatchedData {} + /// The selection process begins by considering all impls, where /// clauses, and so forth that might resolve an obligation. Sometimes /// we'll be able to say definitively that (e.g.) an impl does not @@ -918,20 +921,31 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // and applicable impls. There is a certain set of precedence rules here. match self.tcx().lang_items.to_builtin_kind(obligation.trait_ref.def_id) { - Some(bound) => { - try!(self.assemble_builtin_bound_candidates(bound, stack, &mut candidates)); + Some(ty::BoundCopy) => { + debug!("obligation self ty is {}", + obligation.self_ty().repr(self.tcx())); + try!(self.assemble_candidates_from_impls(obligation, &mut candidates)); + try!(self.assemble_builtin_bound_candidates(ty::BoundCopy, + stack, + &mut candidates)); } None => { - // For the time being, we ignore user-defined impls for builtin-bounds. + // For the time being, we ignore user-defined impls for builtin-bounds, other than + // `Copy`. // (And unboxed candidates only apply to the Fn/FnMut/etc traits.) try!(self.assemble_unboxed_closure_candidates(obligation, &mut candidates)); try!(self.assemble_fn_pointer_candidates(obligation, &mut candidates)); try!(self.assemble_candidates_from_impls(obligation, &mut candidates)); } + + Some(bound) => { + try!(self.assemble_builtin_bound_candidates(bound, stack, &mut candidates)); + } } try!(self.assemble_candidates_from_caller_bounds(obligation, &mut candidates)); + debug!("candidate list size: {}", candidates.vec.len()); Ok(candidates) } @@ -1519,13 +1533,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } ty::BoundCopy => { - if - Some(def_id) == tcx.lang_items.no_copy_bound() || - Some(def_id) == tcx.lang_items.managed_bound() || - ty::has_dtor(tcx, def_id) - { - return Err(Unimplemented); - } + // This is an Opt-In Built-In Trait. + return Ok(ParameterBuiltin) } ty::BoundSync => { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 8a2529701bb..4c4b5d07f50 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -38,6 +38,7 @@ pub use self::IntVarValue::*; pub use self::ExprAdjustment::*; pub use self::vtable_origin::*; pub use self::MethodOrigin::*; +pub use self::CopyImplementationError::*; use back::svh::Svh; use session::Session; @@ -52,8 +53,10 @@ use middle::mem_categorization as mc; use middle::region; use middle::resolve; use middle::resolve_lifetime; +use middle::infer; use middle::stability; use middle::subst::{mod, Subst, Substs, VecPerParamSpace}; +use middle::traits::ObligationCause; use middle::traits; use middle::ty; use middle::ty_fold::{mod, TypeFoldable, TypeFolder, HigherRankedFoldable}; @@ -72,7 +75,7 @@ use std::hash::{Hash, sip, Writer}; use std::mem; use std::ops; use std::rc::Rc; -use std::collections::hash_map::{Occupied, Vacant}; +use std::collections::hash_map::{HashMap, Occupied, Vacant}; use arena::TypedArena; use syntax::abi; use syntax::ast::{CrateNum, DefId, FnStyle, Ident, ItemTrait, LOCAL_CRATE}; @@ -81,7 +84,7 @@ use syntax::ast::{Onceness, StmtExpr, StmtSemi, StructField, UnnamedField}; use syntax::ast::{Visibility}; use syntax::ast_util::{mod, is_local, lit_is_str, local_def, PostExpansionMethod}; use syntax::attr::{mod, AttrMetaMethods}; -use syntax::codemap::Span; +use syntax::codemap::{DUMMY_SP, Span}; use syntax::parse::token::{mod, InternedString}; use syntax::{ast, ast_map}; use std::collections::enum_set::{EnumSet, CLike}; @@ -109,12 +112,16 @@ pub struct field<'tcx> { pub mt: mt<'tcx> } +impl<'tcx> Copy for field<'tcx> {} + #[deriving(Clone, Show)] pub enum ImplOrTraitItemContainer { TraitContainer(ast::DefId), ImplContainer(ast::DefId), } +impl Copy for ImplOrTraitItemContainer {} + impl ImplOrTraitItemContainer { pub fn id(&self) -> ast::DefId { match *self { @@ -175,6 +182,8 @@ pub enum ImplOrTraitItemId { TypeTraitItemId(ast::DefId), } +impl Copy for ImplOrTraitItemId {} + impl ImplOrTraitItemId { pub fn def_id(&self) -> ast::DefId { match *self { @@ -236,12 +245,16 @@ pub struct AssociatedType { pub container: ImplOrTraitItemContainer, } +impl Copy for AssociatedType {} + #[deriving(Clone, PartialEq, Eq, Hash, Show)] pub struct mt<'tcx> { pub ty: Ty<'tcx>, pub mutbl: ast::Mutability, } +impl<'tcx> Copy for mt<'tcx> {} + #[deriving(Clone, PartialEq, Eq, Hash, Encodable, Decodable, Show)] pub enum TraitStore { /// Box @@ -250,6 +263,8 @@ pub enum TraitStore { RegionTraitStore(Region, ast::Mutability), } +impl Copy for TraitStore {} + #[deriving(Clone, Show)] pub struct field_ty { pub name: Name, @@ -258,6 +273,8 @@ pub struct field_ty { pub origin: ast::DefId, // The DefId of the struct in which the field is declared. } +impl Copy for field_ty {} + // Contains information needed to resolve types and (in the future) look up // the types of AST nodes. #[deriving(PartialEq, Eq, Hash)] @@ -267,11 +284,15 @@ pub struct creader_cache_key { pub len: uint } +impl Copy for creader_cache_key {} + pub enum ast_ty_to_ty_cache_entry<'tcx> { atttce_unresolved, /* not resolved yet */ atttce_resolved(Ty<'tcx>) /* resolved to a type, irrespective of region */ } +impl<'tcx> Copy for ast_ty_to_ty_cache_entry<'tcx> {} + #[deriving(Clone, PartialEq, Decodable, Encodable)] pub struct ItemVariances { pub types: VecPerParamSpace, @@ -286,6 +307,8 @@ pub enum Variance { Bivariant, // T <: T -- e.g., unused type parameter } +impl Copy for Variance {} + #[deriving(Clone, Show)] pub enum AutoAdjustment<'tcx> { AdjustAddEnv(ty::TraitStore), @@ -431,6 +454,8 @@ pub struct param_index { pub index: uint } +impl Copy for param_index {} + #[deriving(Clone, Show)] pub enum MethodOrigin<'tcx> { // fully statically resolved method @@ -485,6 +510,8 @@ pub struct MethodCallee<'tcx> { pub substs: subst::Substs<'tcx> } +impl Copy for MethodCall {} + /// With method calls, we store some extra information in /// side tables (i.e method_map). We use /// MethodCall as a key to index into these tables instead of @@ -510,6 +537,8 @@ pub enum ExprAdjustment { AutoObject } +impl Copy for ExprAdjustment {} + impl MethodCall { pub fn expr(id: ast::NodeId) -> MethodCall { MethodCall { @@ -594,6 +623,8 @@ pub struct TransmuteRestriction<'tcx> { pub id: ast::NodeId, } +impl<'tcx> Copy for TransmuteRestriction<'tcx> {} + /// The data structure to keep track of all the information that typechecker /// generates so that so that it can be reused and doesn't have to be redone /// later on. @@ -746,6 +777,9 @@ pub struct ctxt<'tcx> { /// Caches the representation hints for struct definitions. pub repr_hint_cache: RefCell>>>, + + /// Caches whether types move by default. + pub type_moves_by_default_cache: RefCell,bool>>, } // Flags that we track on types. These flags are propagated upwards @@ -766,6 +800,8 @@ bitflags! { } } +impl Copy for TypeFlags {} + #[deriving(Show)] pub struct TyS<'tcx> { pub sty: sty<'tcx>, @@ -807,6 +843,7 @@ impl<'tcx> PartialEq for InternedTy<'tcx> { self.ty.sty == other.ty.sty } } + impl<'tcx> Eq for InternedTy<'tcx> {} impl<'tcx, S: Writer> Hash for InternedTy<'tcx> { @@ -900,6 +937,8 @@ impl<'tcx> FnOutput<'tcx> { } } +impl<'tcx> Copy for FnOutput<'tcx> {} + /// Signature of a function type, which I have arbitrarily /// decided to use to refer to the input/output types. /// @@ -924,6 +963,8 @@ pub struct ParamTy { pub def_id: DefId } +impl Copy for ParamTy {} + /// A [De Bruijn index][dbi] is a standard means of representing /// regions (and perhaps later types) in a higher-ranked setting. In /// particular, imagine a type like this: @@ -1018,6 +1059,8 @@ pub struct UpvarId { pub closure_expr_id: ast::NodeId, } +impl Copy for UpvarId {} + #[deriving(Clone, PartialEq, Eq, Hash, Show, Encodable, Decodable)] pub enum BorrowKind { /// Data must be immutable and is aliasable. @@ -1064,6 +1107,8 @@ pub enum BorrowKind { MutBorrow } +impl Copy for BorrowKind {} + /// Information describing the borrowing of an upvar. This is computed /// during `typeck`, specifically by `regionck`. The general idea is /// that the compiler analyses treat closures like: @@ -1119,6 +1164,8 @@ pub struct UpvarBorrow { pub type UpvarBorrowMap = FnvHashMap; +impl Copy for UpvarBorrow {} + impl Region { pub fn is_bound(&self) -> bool { match *self { @@ -1136,6 +1183,8 @@ impl Region { } } +impl Copy for Region {} + #[deriving(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Encodable, Decodable, Show)] /// A "free" region `fr` can be interpreted as "some region /// at least as big as the scope `fr.scope`". @@ -1144,6 +1193,8 @@ pub struct FreeRegion { pub bound_region: BoundRegion } +impl Copy for FreeRegion {} + #[deriving(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Encodable, Decodable, Show)] pub enum BoundRegion { /// An anonymous region parameter for a given fn (&T) @@ -1163,6 +1214,8 @@ pub enum BoundRegion { BrEnv } +impl Copy for BoundRegion {} + #[inline] pub fn mk_prim_t<'tcx>(primitive: &'tcx TyS<'static>) -> Ty<'tcx> { // FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx. @@ -1302,6 +1355,8 @@ pub enum IntVarValue { UintType(ast::UintTy), } +impl Copy for IntVarValue {} + #[deriving(Clone, Show)] pub enum terr_vstore_kind { terr_vec, @@ -1310,12 +1365,16 @@ pub enum terr_vstore_kind { terr_trait } +impl Copy for terr_vstore_kind {} + #[deriving(Clone, Show)] pub struct expected_found { pub expected: T, pub found: T } +impl Copy for expected_found {} + // Data structures used in type unification #[deriving(Clone, Show)] pub enum type_err<'tcx> { @@ -1350,6 +1409,8 @@ pub enum type_err<'tcx> { terr_convergence_mismatch(expected_found) } +impl<'tcx> Copy for type_err<'tcx> {} + /// Bounds suitable for a named type parameter like `A` in `fn foo` /// as well as the existential type parameter in an object type. #[deriving(PartialEq, Eq, Hash, Clone, Show)] @@ -1370,6 +1431,8 @@ pub struct ExistentialBounds { pub builtin_bounds: BuiltinBounds } +impl Copy for ExistentialBounds {} + pub type BuiltinBounds = EnumSet; #[deriving(Clone, Encodable, PartialEq, Eq, Decodable, Hash, Show)] @@ -1381,6 +1444,8 @@ pub enum BuiltinBound { BoundSync, } +impl Copy for BuiltinBound {} + pub fn empty_builtin_bounds() -> BuiltinBounds { EnumSet::new() } @@ -1413,21 +1478,29 @@ pub struct TyVid { pub index: uint } +impl Copy for TyVid {} + #[deriving(Clone, PartialEq, Eq, Hash)] pub struct IntVid { pub index: uint } +impl Copy for IntVid {} + #[deriving(Clone, PartialEq, Eq, Hash)] pub struct FloatVid { pub index: uint } +impl Copy for FloatVid {} + #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] pub struct RegionVid { pub index: uint } +impl Copy for RegionVid {} + #[deriving(Clone, PartialEq, Eq, Hash)] pub enum InferTy { TyVar(TyVid), @@ -1441,12 +1514,16 @@ pub enum InferTy { SkolemizedIntTy(uint), } +impl Copy for InferTy {} + #[deriving(Clone, Encodable, Decodable, Eq, Hash, Show)] pub enum InferRegion { ReVar(RegionVid), ReSkolemized(uint, BoundRegion) } +impl Copy for InferRegion {} + impl cmp::PartialEq for InferRegion { fn eq(&self, other: &InferRegion) -> bool { match ((*self), *other) { @@ -1642,6 +1719,7 @@ impl<'tcx> TraitRef<'tcx> { /// bound lifetime parameters are replaced with free ones, but in the /// future I hope to refine the representation of types so as to make /// more distinctions clearer. +#[deriving(Clone)] pub struct ParameterEnvironment<'tcx> { /// A substitution that can be applied to move from /// the "outer" view of a type or method to the "inner" view. @@ -1690,14 +1768,14 @@ impl<'tcx> ParameterEnvironment<'tcx> { } TypeTraitItem(_) => { cx.sess - .bug("ParameterEnvironment::from_item(): \ + .bug("ParameterEnvironment::for_item(): \ can't create a parameter environment \ for type trait items") } } } ast::TypeImplItem(_) => { - cx.sess.bug("ParameterEnvironment::from_item(): \ + cx.sess.bug("ParameterEnvironment::for_item(): \ can't create a parameter environment \ for type impl items") } @@ -1707,7 +1785,7 @@ impl<'tcx> ParameterEnvironment<'tcx> { match *trait_method { ast::RequiredMethod(ref required) => { cx.sess.span_bug(required.span, - "ParameterEnvironment::from_item(): + "ParameterEnvironment::for_item(): can't create a parameter \ environment for required trait \ methods") @@ -1725,7 +1803,7 @@ impl<'tcx> ParameterEnvironment<'tcx> { } TypeTraitItem(_) => { cx.sess - .bug("ParameterEnvironment::from_item(): \ + .bug("ParameterEnvironment::for_item(): \ can't create a parameter environment \ for type trait items") } @@ -1768,6 +1846,10 @@ impl<'tcx> ParameterEnvironment<'tcx> { } } } + Some(ast_map::NodeExpr(..)) => { + // This is a convenience to allow closures to work. + ParameterEnvironment::for_item(cx, cx.map.get_parent(id)) + } _ => { cx.sess.bug(format!("ParameterEnvironment::from_item(): \ `{}` is not an item", @@ -1825,6 +1907,8 @@ pub enum UnboxedClosureKind { FnOnceUnboxedClosureKind, } +impl Copy for UnboxedClosureKind {} + impl UnboxedClosureKind { pub fn trait_did(&self, cx: &ctxt) -> ast::DefId { let result = match *self { @@ -1909,6 +1993,7 @@ pub fn mk_ctxt<'tcx>(s: Session, associated_types: RefCell::new(DefIdMap::new()), selection_cache: traits::SelectionCache::new(), repr_hint_cache: RefCell::new(DefIdMap::new()), + type_moves_by_default_cache: RefCell::new(HashMap::new()), } } @@ -2604,6 +2689,8 @@ pub struct TypeContents { pub bits: u64 } +impl Copy for TypeContents {} + macro_rules! def_type_content_sets( (mod $mname:ident { $($name:ident = $bits:expr),+ }) => { #[allow(non_snake_case)] @@ -2630,7 +2717,6 @@ def_type_content_sets!( OwnsOwned = 0b0000_0000__0000_0001__0000, OwnsDtor = 0b0000_0000__0000_0010__0000, OwnsManaged /* see [1] below */ = 0b0000_0000__0000_0100__0000, - OwnsAffine = 0b0000_0000__0000_1000__0000, OwnsAll = 0b0000_0000__1111_1111__0000, // Things that are reachable by the value in any way (fourth nibble): @@ -2640,24 +2726,12 @@ def_type_content_sets!( ReachesFfiUnsafe = 0b0010_0000__0000_0000__0000, ReachesAll = 0b0011_1111__0000_0000__0000, - // Things that cause values to *move* rather than *copy*. This - // is almost the same as the `Copy` trait, but for managed - // data -- atm, we consider managed data to copy, not move, - // but it does not impl Copy as a pure memcpy is not good - // enough. Yuck. - Moves = 0b0000_0000__0000_1011__0000, - // Things that mean drop glue is necessary NeedsDrop = 0b0000_0000__0000_0111__0000, // Things that prevent values from being considered sized Nonsized = 0b0000_0000__0000_0000__0001, - // Things that make values considered not POD (would be same - // as `Moves`, but for the fact that managed data `@` is - // not considered POD) - Noncopy = 0b0000_0000__0000_1111__0000, - // Bits to set when a managed value is encountered // // [1] Do not set the bits TC::OwnsManaged or @@ -2699,10 +2773,6 @@ impl TypeContents { self.intersects(TC::InteriorUnsized) } - pub fn moves_by_default(&self, _: &ctxt) -> bool { - self.intersects(TC::Moves) - } - pub fn needs_drop(&self, _: &ctxt) -> bool { self.intersects(TC::NeedsDrop) } @@ -2987,15 +3057,10 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents { mc | tc_ty(cx, mt.ty, cache) } - fn apply_lang_items(cx: &ctxt, - did: ast::DefId, - tc: TypeContents) - -> TypeContents - { + fn apply_lang_items(cx: &ctxt, did: ast::DefId, tc: TypeContents) + -> TypeContents { if Some(did) == cx.lang_items.managed_bound() { tc | TC::Managed - } else if Some(did) == cx.lang_items.no_copy_bound() { - tc | TC::OwnsAffine } else if Some(did) == cx.lang_items.unsafe_type() { tc | TC::InteriorUnsafe } else { @@ -3008,7 +3073,7 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents { mutbl: ast::Mutability) -> TypeContents { let b = match mutbl { - ast::MutMutable => TC::ReachesMutable | TC::OwnsAffine, + ast::MutMutable => TC::ReachesMutable, ast::MutImmutable => TC::None, }; b | (TC::ReachesBorrowed).when(region != ty::ReStatic) @@ -3028,14 +3093,7 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents { } }; - // This also prohibits "@once fn" from being copied, which allows it to - // be called. Neither way really makes much sense. - let ot = match cty.onceness { - ast::Once => TC::OwnsAffine, - ast::Many => TC::None, - }; - - st | ot + st } fn object_contents(cx: &ctxt, @@ -3053,9 +3111,8 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents { let mut tc = TC::All; each_inherited_builtin_bound(cx, bounds, traits, |bound| { tc = tc - match bound { - BoundSync | BoundSend => TC::None, + BoundSync | BoundSend | BoundCopy => TC::None, BoundSized => TC::Nonsized, - BoundCopy => TC::Noncopy, }; }); return tc; @@ -3081,8 +3138,38 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents { } } -pub fn type_moves_by_default<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> bool { - type_contents(cx, ty).moves_by_default(cx) +pub fn type_moves_by_default<'tcx>(cx: &ctxt<'tcx>, + ty: Ty<'tcx>, + param_env: &ParameterEnvironment<'tcx>) + -> bool { + if !type_has_params(ty) && !type_has_self(ty) { + match cx.type_moves_by_default_cache.borrow().get(&ty) { + None => {} + Some(&result) => { + debug!("determined whether {} moves by default (cached): {}", + ty_to_string(cx, ty), + result); + return result + } + } + } + + let infcx = infer::new_infer_ctxt(cx); + let mut fulfill_cx = traits::FulfillmentContext::new(); + let obligation = traits::obligation_for_builtin_bound( + cx, + ObligationCause::misc(DUMMY_SP), + ty, + ty::BoundCopy).unwrap(); + fulfill_cx.register_obligation(cx, obligation); + let result = !fulfill_cx.select_all_or_error(&infcx, + param_env, + cx).is_ok(); + cx.type_moves_by_default_cache.borrow_mut().insert(ty, result); + debug!("determined whether {} moves by default: {}", + ty_to_string(cx, ty), + result); + result } pub fn is_ffi_safe<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> bool { @@ -3214,6 +3301,8 @@ pub enum Representability { SelfRecursive, } +impl Copy for Representability {} + /// Check whether a type is representable. This means it cannot contain unboxed /// structural recursion. This check is needed for structs and enums. pub fn is_type_representable<'tcx>(cx: &ctxt<'tcx>, sp: Span, ty: Ty<'tcx>) @@ -3996,6 +4085,8 @@ pub enum ExprKind { RvalueStmtExpr } +impl Copy for ExprKind {} + pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind { if tcx.method_map.borrow().contains_key(&MethodCall::expr(expr.id)) { // Overloaded operations are generally calls, and hence they are @@ -4555,6 +4646,8 @@ pub struct AssociatedTypeInfo { pub name: ast::Name, } +impl Copy for AssociatedTypeInfo {} + impl PartialOrd for AssociatedTypeInfo { fn partial_cmp(&self, other: &AssociatedTypeInfo) -> Option { Some(self.index.cmp(&other.index)) @@ -4738,6 +4831,8 @@ pub enum DtorKind { TraitDtor(DefId, bool) } +impl Copy for DtorKind {} + impl DtorKind { pub fn is_present(&self) -> bool { match *self { @@ -5125,6 +5220,8 @@ pub struct UnboxedClosureUpvar<'tcx> { pub ty: Ty<'tcx>, } +impl<'tcx> Copy for UnboxedClosureUpvar<'tcx> {} + // Returns a list of `UnboxedClosureUpvar`s for each upvar. pub fn unboxed_closure_upvars<'tcx>(tcx: &ctxt<'tcx>, closure_id: ast::DefId, substs: &Substs<'tcx>) -> Vec> { @@ -5954,6 +6051,8 @@ pub enum ExplicitSelfCategory { ByBoxExplicitSelfCategory, } +impl Copy for ExplicitSelfCategory {} + /// Pushes all the lifetimes in the given type onto the given list. A /// "lifetime in a type" is a lifetime specified by a reference or a lifetime /// in a list of type substitutions. This does *not* traverse into nominal @@ -6023,6 +6122,8 @@ pub struct Freevar { pub span: Span } +impl Copy for Freevar {} + pub type FreevarMap = NodeMap>; pub type CaptureModeMap = NodeMap; @@ -6122,6 +6223,8 @@ impl DebruijnIndex { } } +impl Copy for DebruijnIndex {} + impl<'tcx> Repr<'tcx> for AutoAdjustment<'tcx> { fn repr(&self, tcx: &ctxt<'tcx>) -> String { match *self { @@ -6229,3 +6332,43 @@ pub fn make_substs_for_receiver_types<'tcx>(tcx: &ty::ctxt<'tcx>, trait_ref.substs.clone().with_method(meth_tps, meth_regions) } +pub enum CopyImplementationError { + FieldDoesNotImplementCopy(ast::Name), + VariantDoesNotImplementCopy(ast::Name), + TypeIsStructural, +} + +impl Copy for CopyImplementationError {} + +pub fn can_type_implement_copy<'tcx>(tcx: &ctxt<'tcx>, + self_type: Ty<'tcx>, + param_env: &ParameterEnvironment<'tcx>) + -> Result<(),CopyImplementationError> { + match self_type.sty { + ty::ty_struct(struct_did, ref substs) => { + let fields = ty::struct_fields(tcx, struct_did, substs); + for field in fields.iter() { + if type_moves_by_default(tcx, field.mt.ty, param_env) { + return Err(FieldDoesNotImplementCopy(field.name)) + } + } + } + ty::ty_enum(enum_did, ref substs) => { + let enum_variants = ty::enum_variants(tcx, enum_did); + for variant in enum_variants.iter() { + for variant_arg_type in variant.args.iter() { + let substd_arg_type = + variant_arg_type.subst(tcx, substs); + if type_moves_by_default(tcx, + substd_arg_type, + param_env) { + return Err(VariantDoesNotImplementCopy(variant.name)) + } + } + } + } + _ => return Err(TypeIsStructural), + } + + Ok(()) +} diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 981b58a3b7b..c7b5e1e8de9 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -55,6 +55,8 @@ pub enum OptLevel { Aggressive // -O3 } +impl Copy for OptLevel {} + #[deriving(Clone, PartialEq)] pub enum DebugInfoLevel { NoDebugInfo, @@ -62,6 +64,8 @@ pub enum DebugInfoLevel { FullDebugInfo, } +impl Copy for DebugInfoLevel {} + #[deriving(Clone, PartialEq, PartialOrd, Ord, Eq)] pub enum OutputType { OutputTypeBitcode, @@ -71,6 +75,8 @@ pub enum OutputType { OutputTypeExe, } +impl Copy for OutputType {} + #[deriving(Clone)] pub struct Options { // The crate config requested for the session, which may be combined @@ -87,7 +93,7 @@ pub struct Options { // parsed code. It remains mutable in case its replacements wants to use // this. pub addl_lib_search_paths: RefCell>, - pub libs: Vec<(String, cstore::NativeLibaryKind)>, + pub libs: Vec<(String, cstore::NativeLibraryKind)>, pub maybe_sysroot: Option, pub target_triple: String, // User-specified cfg meta items. The compiler itself will add additional @@ -221,6 +227,8 @@ pub enum EntryFnType { EntryNone, } +impl Copy for EntryFnType {} + #[deriving(PartialEq, PartialOrd, Clone, Ord, Eq, Hash)] pub enum CrateType { CrateTypeExecutable, @@ -229,6 +237,8 @@ pub enum CrateType { CrateTypeStaticlib, } +impl Copy for CrateType {} + macro_rules! debugging_opts( ([ $opt:ident ] $cnt:expr ) => ( pub const $opt: u64 = 1 << $cnt; diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index ea252d9fd20..30318cc129c 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -25,6 +25,8 @@ use syntax::visit::Visitor; #[deriving(Clone,Show)] pub struct ErrorReported; +impl Copy for ErrorReported {} + pub fn time(do_it: bool, what: &str, u: U, f: |U| -> T) -> T { thread_local!(static DEPTH: Cell = Cell::new(0)); if !do_it { return f(u); } diff --git a/src/librustc/util/nodemap.rs b/src/librustc/util/nodemap.rs index 4dd6306c3c0..d1816c655fa 100644 --- a/src/librustc/util/nodemap.rs +++ b/src/librustc/util/nodemap.rs @@ -71,6 +71,9 @@ pub mod DefIdSet { #[deriving(Clone, Default)] pub struct FnvHasher; +impl Copy for FnvHasher {} + +#[allow(missing_copy_implementations)] pub struct FnvState(u64); impl Hasher for FnvHasher { diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index b6441ab4944..d143d05acfe 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -49,12 +49,16 @@ pub enum PpSourceMode { PpmExpandedHygiene, } +impl Copy for PpSourceMode {} + #[deriving(PartialEq, Show)] pub enum PpMode { PpmSource(PpSourceMode), PpmFlowGraph, } +impl Copy for PpMode {} + pub fn parse_pretty(sess: &Session, name: &str) -> (PpMode, Option) { let mut split = name.splitn(1, '='); let first = split.next().unwrap(); diff --git a/src/librustc_llvm/diagnostic.rs b/src/librustc_llvm/diagnostic.rs index d705c82dd9a..04196feafd2 100644 --- a/src/librustc_llvm/diagnostic.rs +++ b/src/librustc_llvm/diagnostic.rs @@ -24,6 +24,8 @@ pub enum OptimizationDiagnosticKind { OptimizationFailure, } +impl Copy for OptimizationDiagnosticKind {} + impl OptimizationDiagnosticKind { pub fn describe(self) -> &'static str { match self { @@ -43,6 +45,8 @@ pub struct OptimizationDiagnostic { pub message: TwineRef, } +impl Copy for OptimizationDiagnostic {} + impl OptimizationDiagnostic { unsafe fn unpack(kind: OptimizationDiagnosticKind, di: DiagnosticInfoRef) -> OptimizationDiagnostic { @@ -72,6 +76,8 @@ pub enum Diagnostic { UnknownDiagnostic(DiagnosticInfoRef), } +impl Copy for Diagnostic {} + impl Diagnostic { pub unsafe fn unpack(di: DiagnosticInfoRef) -> Diagnostic { let kind = super::LLVMGetDiagInfoKind(di); diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index a8211c0c9ea..23dad21e530 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -77,12 +77,16 @@ pub enum CallConv { X86_64_Win64 = 79, } +impl Copy for CallConv {} + pub enum Visibility { LLVMDefaultVisibility = 0, HiddenVisibility = 1, ProtectedVisibility = 2, } +impl Copy for Visibility {} + // This enum omits the obsolete (and no-op) linkage types DLLImportLinkage, // DLLExportLinkage, GhostLinkage and LinkOnceODRAutoHideLinkage. // LinkerPrivateLinkage and LinkerPrivateWeakLinkage are not included either; @@ -101,6 +105,8 @@ pub enum Linkage { CommonLinkage = 14, } +impl Copy for Linkage {} + #[repr(C)] #[deriving(Show)] pub enum DiagnosticSeverity { @@ -110,6 +116,8 @@ pub enum DiagnosticSeverity { Note, } +impl Copy for DiagnosticSeverity {} + bitflags! { flags Attribute : u32 { const ZExtAttribute = 1 << 0, @@ -141,6 +149,8 @@ bitflags! { } } +impl Copy for Attribute {} + #[repr(u64)] pub enum OtherAttribute { // The following are not really exposed in @@ -162,16 +172,22 @@ pub enum OtherAttribute { NonNullAttribute = 1 << 44, } +impl Copy for OtherAttribute {} + pub enum SpecialAttribute { DereferenceableAttribute(u64) } +impl Copy for SpecialAttribute {} + #[repr(C)] pub enum AttributeSet { ReturnIndex = 0, FunctionIndex = !0 } +impl Copy for AttributeSet {} + pub trait AttrHelper { fn apply_llfn(&self, idx: c_uint, llfn: ValueRef); fn apply_callsite(&self, idx: c_uint, callsite: ValueRef); @@ -271,6 +287,8 @@ pub enum IntPredicate { IntSLE = 41, } +impl Copy for IntPredicate {} + // enum for the LLVM RealPredicate type pub enum RealPredicate { RealPredicateFalse = 0, @@ -291,6 +309,8 @@ pub enum RealPredicate { RealPredicateTrue = 15, } +impl Copy for RealPredicate {} + // The LLVM TypeKind type - must stay in sync with the def of // LLVMTypeKind in llvm/include/llvm-c/Core.h #[deriving(PartialEq)] @@ -314,6 +334,8 @@ pub enum TypeKind { X86_MMX = 15, } +impl Copy for TypeKind {} + #[repr(C)] pub enum AtomicBinOp { AtomicXchg = 0, @@ -329,6 +351,8 @@ pub enum AtomicBinOp { AtomicUMin = 10, } +impl Copy for AtomicBinOp {} + #[repr(C)] pub enum AtomicOrdering { NotAtomic = 0, @@ -341,6 +365,8 @@ pub enum AtomicOrdering { SequentiallyConsistent = 7 } +impl Copy for AtomicOrdering {} + // Consts for the LLVMCodeGenFileType type (in include/llvm/c/TargetMachine.h) #[repr(C)] pub enum FileType { @@ -348,6 +374,8 @@ pub enum FileType { ObjectFileType = 1 } +impl Copy for FileType {} + pub enum MetadataType { MD_dbg = 0, MD_tbaa = 1, @@ -357,12 +385,16 @@ pub enum MetadataType { MD_tbaa_struct = 5 } +impl Copy for MetadataType {} + // Inline Asm Dialect pub enum AsmDialect { AD_ATT = 0, AD_Intel = 1 } +impl Copy for AsmDialect {} + #[deriving(PartialEq, Clone)] #[repr(C)] pub enum CodeGenOptLevel { @@ -372,6 +404,8 @@ pub enum CodeGenOptLevel { CodeGenLevelAggressive = 3, } +impl Copy for CodeGenOptLevel {} + #[deriving(PartialEq)] #[repr(C)] pub enum RelocMode { @@ -381,6 +415,8 @@ pub enum RelocMode { RelocDynamicNoPic = 3, } +impl Copy for RelocMode {} + #[repr(C)] pub enum CodeGenModel { CodeModelDefault = 0, @@ -391,6 +427,8 @@ pub enum CodeGenModel { CodeModelLarge = 5, } +impl Copy for CodeGenModel {} + #[repr(C)] pub enum DiagnosticKind { DK_InlineAsm = 0, @@ -403,47 +441,70 @@ pub enum DiagnosticKind { DK_OptimizationFailure, } +impl Copy for DiagnosticKind {} + // Opaque pointer types +#[allow(missing_copy_implementations)] pub enum Module_opaque {} pub type ModuleRef = *mut Module_opaque; +#[allow(missing_copy_implementations)] pub enum Context_opaque {} pub type ContextRef = *mut Context_opaque; +#[allow(missing_copy_implementations)] pub enum Type_opaque {} pub type TypeRef = *mut Type_opaque; +#[allow(missing_copy_implementations)] pub enum Value_opaque {} pub type ValueRef = *mut Value_opaque; +#[allow(missing_copy_implementations)] pub enum BasicBlock_opaque {} pub type BasicBlockRef = *mut BasicBlock_opaque; +#[allow(missing_copy_implementations)] pub enum Builder_opaque {} pub type BuilderRef = *mut Builder_opaque; +#[allow(missing_copy_implementations)] pub enum ExecutionEngine_opaque {} pub type ExecutionEngineRef = *mut ExecutionEngine_opaque; +#[allow(missing_copy_implementations)] pub enum MemoryBuffer_opaque {} pub type MemoryBufferRef = *mut MemoryBuffer_opaque; +#[allow(missing_copy_implementations)] pub enum PassManager_opaque {} pub type PassManagerRef = *mut PassManager_opaque; +#[allow(missing_copy_implementations)] pub enum PassManagerBuilder_opaque {} pub type PassManagerBuilderRef = *mut PassManagerBuilder_opaque; +#[allow(missing_copy_implementations)] pub enum Use_opaque {} pub type UseRef = *mut Use_opaque; +#[allow(missing_copy_implementations)] pub enum TargetData_opaque {} pub type TargetDataRef = *mut TargetData_opaque; +#[allow(missing_copy_implementations)] pub enum ObjectFile_opaque {} pub type ObjectFileRef = *mut ObjectFile_opaque; +#[allow(missing_copy_implementations)] pub enum SectionIterator_opaque {} pub type SectionIteratorRef = *mut SectionIterator_opaque; +#[allow(missing_copy_implementations)] pub enum Pass_opaque {} pub type PassRef = *mut Pass_opaque; +#[allow(missing_copy_implementations)] pub enum TargetMachine_opaque {} pub type TargetMachineRef = *mut TargetMachine_opaque; +#[allow(missing_copy_implementations)] pub enum Archive_opaque {} pub type ArchiveRef = *mut Archive_opaque; +#[allow(missing_copy_implementations)] pub enum Twine_opaque {} pub type TwineRef = *mut Twine_opaque; +#[allow(missing_copy_implementations)] pub enum DiagnosticInfo_opaque {} pub type DiagnosticInfoRef = *mut DiagnosticInfo_opaque; +#[allow(missing_copy_implementations)] pub enum DebugLoc_opaque {} pub type DebugLocRef = *mut DebugLoc_opaque; +#[allow(missing_copy_implementations)] pub enum SMDiagnostic_opaque {} pub type SMDiagnosticRef = *mut SMDiagnostic_opaque; @@ -454,6 +515,7 @@ pub mod debuginfo { pub use self::DIDescriptorFlags::*; use super::{ValueRef}; + #[allow(missing_copy_implementations)] pub enum DIBuilder_opaque {} pub type DIBuilderRef = *mut DIBuilder_opaque; @@ -490,6 +552,8 @@ pub mod debuginfo { FlagLValueReference = 1 << 14, FlagRValueReference = 1 << 15 } + + impl Copy for DIDescriptorFlags {} } @@ -2123,6 +2187,7 @@ pub fn get_param(llfn: ValueRef, index: c_uint) -> ValueRef { } } +#[allow(missing_copy_implementations)] pub enum RustString_opaque {} pub type RustStringRef = *mut RustString_opaque; type RustStringRepr = *mut RefCell>; diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index a919fe686ab..0ed6ae31171 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -33,6 +33,17 @@ use std::sync::{Arc, Mutex}; use std::task::TaskBuilder; use libc::{c_uint, c_int, c_void}; +#[deriving(Clone, PartialEq, PartialOrd, Ord, Eq)] +pub enum OutputType { + OutputTypeBitcode, + OutputTypeAssembly, + OutputTypeLlvmAssembly, + OutputTypeObject, + OutputTypeExe, +} + +impl Copy for OutputType {} + pub fn llvm_err(handler: &diagnostic::Handler, msg: String) -> ! { unsafe { let cstr = llvm::LLVMRustGetLastError(); diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index 1482422b8d0..2a698a898fe 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -249,7 +249,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { self.collecting = true; self.visit_pat(&*arg.pat); self.collecting = false; - let span_utils = self.span; + let span_utils = self.span.clone(); for &(id, ref p, _, _) in self.collected_paths.iter() { let typ = ppaux::ty_to_string(&self.analysis.ty_cx, (*self.analysis.ty_cx.node_types.borrow())[id]); diff --git a/src/librustc_trans/save/recorder.rs b/src/librustc_trans/save/recorder.rs index f0bb441145c..c15ff1d7f0a 100644 --- a/src/librustc_trans/save/recorder.rs +++ b/src/librustc_trans/save/recorder.rs @@ -87,6 +87,8 @@ pub enum Row { FnRef, } +impl Copy for Row {} + impl<'a> FmtStrs<'a> { pub fn new(rec: Box, span: SpanUtils<'a>, krate: String) -> FmtStrs<'a> { FmtStrs { @@ -223,7 +225,10 @@ impl<'a> FmtStrs<'a> { if self.recorder.dump_spans { if dump_spans { - self.recorder.dump_span(self.span, label, span, Some(sub_span)); + self.recorder.dump_span(self.span.clone(), + label, + span, + Some(sub_span)); } return; } diff --git a/src/librustc_trans/save/span_utils.rs b/src/librustc_trans/save/span_utils.rs index f76f2bea566..49e8e0fd347 100644 --- a/src/librustc_trans/save/span_utils.rs +++ b/src/librustc_trans/save/span_utils.rs @@ -21,6 +21,7 @@ use syntax::parse::lexer::{Reader,StringReader}; use syntax::parse::token; use syntax::parse::token::{keywords, Token}; +#[deriving(Clone)] pub struct SpanUtils<'a> { pub sess: &'a Session, pub err_count: Cell, diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index f5155852aa0..1ed06938e95 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -231,6 +231,8 @@ use syntax::ptr::P; #[deriving(Show)] struct ConstantExpr<'a>(&'a ast::Expr); +impl<'a> Copy for ConstantExpr<'a> {} + impl<'a> ConstantExpr<'a> { fn eq(self, other: ConstantExpr<'a>, tcx: &ty::ctxt) -> bool { let ConstantExpr(expr) = self; @@ -308,6 +310,8 @@ pub enum BranchKind { CompareSliceLength } +impl Copy for BranchKind {} + pub enum OptResult<'blk, 'tcx: 'blk> { SingleResult(Result<'blk, 'tcx>), RangeResult(Result<'blk, 'tcx>, Result<'blk, 'tcx>), @@ -321,6 +325,8 @@ pub enum TransBindingMode { TrByRef, } +impl Copy for TransBindingMode {} + /// Information about a pattern binding: /// - `llmatch` is a pointer to a stack slot. The stack slot contains a /// pointer into the value being matched. Hence, llmatch has type `T**` @@ -337,6 +343,8 @@ pub struct BindingInfo<'tcx> { pub ty: Ty<'tcx>, } +impl<'tcx> Copy for BindingInfo<'tcx> {} + type BindingsMap<'tcx> = FnvHashMap>; struct ArmData<'p, 'blk, 'tcx: 'blk> { @@ -543,7 +551,11 @@ fn enter_opt<'a, 'p, 'blk, 'tcx>( check_match::Constructor::Variant(def_id) }; - let mcx = check_match::MatchCheckCtxt { tcx: bcx.tcx() }; + let param_env = ty::empty_parameter_environment(); + let mcx = check_match::MatchCheckCtxt { + tcx: bcx.tcx(), + param_env: param_env, + }; enter_match(bcx, dm, m, col, val, |pats| check_match::specialize(&mcx, pats.as_slice(), &ctor, col, variant_size) ) @@ -1001,7 +1013,10 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, node_id_type(bcx, pat_id) }; - let mcx = check_match::MatchCheckCtxt { tcx: bcx.tcx() }; + let mcx = check_match::MatchCheckCtxt { + tcx: bcx.tcx(), + param_env: ty::empty_parameter_environment(), + }; let adt_vals = if any_irrefutable_adt_pat(bcx.tcx(), m, col) { let repr = adt::represent_type(bcx.ccx(), left_ty); let arg_count = adt::num_args(&*repr, 0); @@ -1254,7 +1269,8 @@ fn is_discr_reassigned(bcx: Block, discr: &ast::Expr, body: &ast::Expr) -> bool reassigned: false }; { - let mut visitor = euv::ExprUseVisitor::new(&mut rc, bcx); + let param_env = ty::empty_parameter_environment(); + let mut visitor = euv::ExprUseVisitor::new(&mut rc, bcx, param_env); visitor.walk_expr(body); } rc.reassigned @@ -1312,12 +1328,15 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &ast::Pat, let variable_ty = node_id_type(bcx, p_id); let llvariable_ty = type_of::type_of(ccx, variable_ty); let tcx = bcx.tcx(); + let param_env = ty::empty_parameter_environment(); let llmatch; let trmode; match bm { ast::BindByValue(_) - if !ty::type_moves_by_default(tcx, variable_ty) || reassigned => { + if !ty::type_moves_by_default(tcx, + variable_ty, + ¶m_env) || reassigned => { llmatch = alloca_no_lifetime(bcx, llvariable_ty.ptr_to(), "__llmatch"); diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs index 2f0f373325a..e273a56ce02 100644 --- a/src/librustc_trans/trans/adt.rs +++ b/src/librustc_trans/trans/adt.rs @@ -287,8 +287,11 @@ pub enum PointerField { FatPointer(uint) } +impl Copy for PointerField {} + impl<'tcx> Case<'tcx> { - fn is_zerolen<'a>(&self, cx: &CrateContext<'a, 'tcx>, scapegoat: Ty<'tcx>) -> bool { + fn is_zerolen<'a>(&self, cx: &CrateContext<'a, 'tcx>, scapegoat: Ty<'tcx>) + -> bool { mk_struct(cx, self.tys.as_slice(), false, scapegoat).size == 0 } diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 3090119788c..cef12616cf2 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -90,6 +90,7 @@ use libc::{c_uint, uint64_t}; use std::c_str::ToCStr; use std::cell::{Cell, RefCell}; use std::collections::HashSet; +use std::mem; use std::rc::Rc; use std::{i8, i16, i32, i64}; use syntax::abi::{Rust, RustCall, RustIntrinsic, Abi}; @@ -562,6 +563,8 @@ pub fn maybe_name_value(cx: &CrateContext, v: ValueRef, s: &str) { // Used only for creating scalar comparison glue. pub enum scalar_type { nil_type, signed_int, unsigned_int, floating_point, } +impl Copy for scalar_type {} + pub fn compare_scalar_types<'blk, 'tcx>(cx: Block<'blk, 'tcx>, lhs: ValueRef, rhs: ValueRef, @@ -813,7 +816,10 @@ pub fn iter_structural_ty<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>, in iter_structural_ty") } } - _ => cx.sess().unimpl("type in iter_structural_ty") + _ => { + cx.sess().unimpl(format!("type in iter_structural_ty: {}", + ty_to_string(cx.tcx(), t)).as_slice()) + } } return cx; } @@ -1778,6 +1784,14 @@ pub fn build_return_block<'blk, 'tcx>(fcx: &FunctionContext<'blk, 'tcx>, } } +#[deriving(Clone, Eq, PartialEq)] +pub enum IsUnboxedClosureFlag { + NotUnboxedClosure, + IsUnboxedClosure, +} + +impl Copy for IsUnboxedClosureFlag {} + // trans_closure: Builds an LLVM function out of a source function. // If the function closes over its environment a closure will be // returned. @@ -2182,6 +2196,8 @@ pub enum ValueOrigin { InlinedCopy, } +impl Copy for ValueOrigin {} + /// Set the appropriate linkage for an LLVM `ValueRef` (function or global). /// If the `llval` is the direct translation of a specific Rust item, `id` /// should be set to the `NodeId` of that item. (This mapping should be @@ -3036,7 +3052,11 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet) { fn next(&mut self) -> Option { let old = self.cur; if !old.is_null() { - self.cur = unsafe { (self.step)(old) }; + self.cur = unsafe { + let step: unsafe extern "C" fn(ValueRef) -> ValueRef = + mem::transmute_copy(&self.step); + step(old) + }; Some(old) } else { None diff --git a/src/librustc_trans/trans/basic_block.rs b/src/librustc_trans/trans/basic_block.rs index 328c8e616c4..b55c268d9a9 100644 --- a/src/librustc_trans/trans/basic_block.rs +++ b/src/librustc_trans/trans/basic_block.rs @@ -15,6 +15,8 @@ use std::iter::{Filter, Map}; pub struct BasicBlock(pub BasicBlockRef); +impl Copy for BasicBlock {} + pub type Preds<'a> = Map<'a, Value, BasicBlock, Filter<'a, Value, Users>>; /// Wrapper for LLVM BasicBlockRef diff --git a/src/librustc_trans/trans/cabi.rs b/src/librustc_trans/trans/cabi.rs index 518b0ba73f8..7aabd998f7a 100644 --- a/src/librustc_trans/trans/cabi.rs +++ b/src/librustc_trans/trans/cabi.rs @@ -31,6 +31,8 @@ pub enum ArgKind { Ignore, } +impl Copy for ArgKind {} + /// Information about how a specific C type /// should be passed to or returned from a function /// @@ -48,6 +50,8 @@ pub struct ArgType { pub attr: option::Option } +impl Copy for ArgType {} + impl ArgType { pub fn direct(ty: Type, cast: option::Option, pad: option::Option, diff --git a/src/librustc_trans/trans/cabi_x86_64.rs b/src/librustc_trans/trans/cabi_x86_64.rs index 69ee5301d18..00c91ddebb3 100644 --- a/src/librustc_trans/trans/cabi_x86_64.rs +++ b/src/librustc_trans/trans/cabi_x86_64.rs @@ -40,6 +40,8 @@ enum RegClass { Memory } +impl Copy for RegClass {} + trait TypeMethods { fn is_reg_ty(&self) -> bool; } diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index 746109ef113..ff7ab91c39a 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -63,6 +63,8 @@ pub struct MethodData { pub llself: ValueRef, } +impl Copy for MethodData {} + pub enum CalleeData<'tcx> { Closure(Datum<'tcx, Lvalue>), @@ -1200,6 +1202,8 @@ pub enum AutorefArg { DoAutorefArg(ast::NodeId) } +impl Copy for AutorefArg {} + pub fn trans_arg_datum<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, formal_arg_ty: Ty<'tcx>, arg_datum: Datum<'tcx, Expr>, diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs index 33393ba76c5..ba3e70fe036 100644 --- a/src/librustc_trans/trans/cleanup.rs +++ b/src/librustc_trans/trans/cleanup.rs @@ -55,6 +55,8 @@ pub struct CustomScopeIndex { index: uint } +impl Copy for CustomScopeIndex {} + pub const EXIT_BREAK: uint = 0; pub const EXIT_LOOP: uint = 1; pub const EXIT_MAX: uint = 2; @@ -88,11 +90,15 @@ pub enum EarlyExitLabel { LoopExit(ast::NodeId, uint) } +impl Copy for EarlyExitLabel {} + pub struct CachedEarlyExit { label: EarlyExitLabel, cleanup_block: BasicBlockRef, } +impl Copy for CachedEarlyExit {} + pub trait Cleanup<'tcx> { fn must_unwind(&self) -> bool; fn clean_on_unwind(&self) -> bool; @@ -111,6 +117,8 @@ pub enum ScopeId { CustomScope(CustomScopeIndex) } +impl Copy for ScopeId {} + impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> { /// Invoked when we start to trans the code contained within a new cleanup scope. fn push_ast_cleanup_scope(&self, debug_loc: NodeInfo) { @@ -876,6 +884,8 @@ pub struct DropValue<'tcx> { zero: bool } +impl<'tcx> Copy for DropValue<'tcx> {} + impl<'tcx> Cleanup<'tcx> for DropValue<'tcx> { fn must_unwind(&self) -> bool { self.must_unwind @@ -910,12 +920,16 @@ pub enum Heap { HeapExchange } +impl Copy for Heap {} + pub struct FreeValue<'tcx> { ptr: ValueRef, heap: Heap, content_ty: Ty<'tcx> } +impl<'tcx> Copy for FreeValue<'tcx> {} + impl<'tcx> Cleanup<'tcx> for FreeValue<'tcx> { fn must_unwind(&self) -> bool { true @@ -950,6 +964,8 @@ pub struct FreeSlice { heap: Heap, } +impl Copy for FreeSlice {} + impl<'tcx> Cleanup<'tcx> for FreeSlice { fn must_unwind(&self) -> bool { true @@ -981,6 +997,8 @@ pub struct LifetimeEnd { ptr: ValueRef, } +impl Copy for LifetimeEnd {} + impl<'tcx> Cleanup<'tcx> for LifetimeEnd { fn must_unwind(&self) -> bool { false diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index bb4df00bd94..b03f5ff8ecc 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -107,6 +107,8 @@ pub struct EnvValue<'tcx> { datum: Datum<'tcx, Lvalue> } +impl<'tcx> Copy for EnvValue<'tcx> {} + impl<'tcx> EnvValue<'tcx> { pub fn to_string<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> String { format!("{}({})", self.action, self.datum.to_string(ccx)) diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index a8256176c26..77412b00299 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -127,6 +127,8 @@ pub struct tydesc_info<'tcx> { pub name: ValueRef, } +impl<'tcx> Copy for tydesc_info<'tcx> {} + /* * A note on nomenclature of linking: "extern", "foreign", and "upcall". * @@ -158,6 +160,8 @@ pub struct NodeInfo { pub span: Span, } +impl Copy for NodeInfo {} + pub fn expr_info(expr: &ast::Expr) -> NodeInfo { NodeInfo { id: expr.id, span: expr.span } } @@ -867,10 +871,11 @@ pub enum ExprOrMethodCall { MethodCall(ty::MethodCall) } +impl Copy for ExprOrMethodCall {} + pub fn node_id_substs<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, node: ExprOrMethodCall) - -> subst::Substs<'tcx> -{ + -> subst::Substs<'tcx> { let tcx = bcx.tcx(); let substs = match node { diff --git a/src/librustc_trans/trans/datum.rs b/src/librustc_trans/trans/datum.rs index 532ef690818..23a261842b2 100644 --- a/src/librustc_trans/trans/datum.rs +++ b/src/librustc_trans/trans/datum.rs @@ -46,6 +46,8 @@ pub struct Datum<'tcx, K> { pub kind: K, } +impl<'tcx,K:Copy> Copy for Datum<'tcx,K> {} + pub struct DatumBlock<'blk, 'tcx: 'blk, K> { pub bcx: Block<'blk, 'tcx>, pub datum: Datum<'tcx, K>, @@ -66,6 +68,8 @@ pub enum Expr { #[deriving(Clone, Show)] pub struct Lvalue; +impl Copy for Lvalue {} + #[deriving(Show)] pub struct Rvalue { pub mode: RvalueMode @@ -91,6 +95,8 @@ pub enum RvalueMode { ByValue, } +impl Copy for RvalueMode {} + pub fn immediate_rvalue<'tcx>(val: ValueRef, ty: Ty<'tcx>) -> Datum<'tcx, Rvalue> { return Datum::new(val, ty, Rvalue::new(ByValue)); } @@ -529,11 +535,19 @@ impl<'tcx, K: KindOps + fmt::Show> Datum<'tcx, K> { /// Copies the value into a new location. This function always preserves the existing datum as /// a valid value. Therefore, it does not consume `self` and, also, cannot be applied to affine /// values (since they must never be duplicated). - pub fn shallow_copy<'blk>(&self, - bcx: Block<'blk, 'tcx>, - dst: ValueRef) - -> Block<'blk, 'tcx> { - assert!(!ty::type_moves_by_default(bcx.tcx(), self.ty)); + pub fn shallow_copy<'blk, 'tcx>(&self, + bcx: Block<'blk, 'tcx>, + dst: ValueRef) + -> Block<'blk, 'tcx> { + /*! + * Copies the value into a new location. This function always + * preserves the existing datum as a valid value. Therefore, + * it does not consume `self` and, also, cannot be applied to + * affine values (since they must never be duplicated). + */ + + let param_env = ty::empty_parameter_environment(); + assert!(!ty::type_moves_by_default(bcx.tcx(), self.ty, ¶m_env)); self.shallow_copy_raw(bcx, dst) } diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index 6c75086fec6..88a66320c0e 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -251,6 +251,8 @@ static FLAGS_NONE: c_uint = 0; #[deriving(Show, Hash, Eq, PartialEq, Clone)] struct UniqueTypeId(ast::Name); +impl Copy for UniqueTypeId {} + // The TypeMap is where the CrateDebugContext holds the type metadata nodes // created so far. The metadata nodes are indexed by UniqueTypeId, and, for // faster lookup, also by Ty. The TypeMap is responsible for creating @@ -2323,6 +2325,8 @@ enum EnumDiscriminantInfo { NoDiscriminant } +impl Copy for EnumDiscriminantInfo {} + // Returns a tuple of (1) type_metadata_stub of the variant, (2) the llvm_type // of the variant, and (3) a MemberDescriptionFactory for producing the // descriptions of the fields of the variant. This is a rudimentary version of a @@ -3048,6 +3052,8 @@ enum DebugLocation { UnknownLocation } +impl Copy for DebugLocation {} + impl DebugLocation { fn new(scope: DIScope, line: uint, col: uint) -> DebugLocation { KnownLocation { diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index d130dc0a55b..e3e6fff7234 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -79,6 +79,8 @@ pub enum Dest { Ignore, } +impl Copy for Dest {} + impl Dest { pub fn to_string(&self, ccx: &CrateContext) -> String { match *self { @@ -1882,6 +1884,8 @@ pub enum cast_kind { cast_other, } +impl Copy for cast_kind {} + pub fn cast_type_kind<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> cast_kind { match t.sty { ty::ty_char => cast_integral, diff --git a/src/librustc_trans/trans/mod.rs b/src/librustc_trans/trans/mod.rs index c00c477f4b8..9234dfc48bd 100644 --- a/src/librustc_trans/trans/mod.rs +++ b/src/librustc_trans/trans/mod.rs @@ -59,6 +59,8 @@ pub struct ModuleTranslation { pub llmod: ModuleRef, } +impl Copy for ModuleTranslation {} + pub struct CrateTranslation { pub modules: Vec, pub metadata_module: ModuleTranslation, diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs index 00f938191f8..18ea8055a4e 100644 --- a/src/librustc_trans/trans/tvec.rs +++ b/src/librustc_trans/trans/tvec.rs @@ -96,6 +96,8 @@ pub struct VecTypes<'tcx> { pub llunit_alloc_size: u64 } +impl<'tcx> Copy for VecTypes<'tcx> {} + impl<'tcx> VecTypes<'tcx> { pub fn to_string<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> String { format!("VecTypes {{unit_ty={}, llunit_ty={}, \ @@ -301,8 +303,6 @@ pub fn write_content<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, 1 => expr::trans_into(bcx, &**element, SaveIn(lldest)), count => { let elem = unpack_datum!(bcx, expr::trans(bcx, &**element)); - assert!(!ty::type_moves_by_default(bcx.tcx(), elem.ty)); - let bcx = iter_vec_loop(bcx, lldest, vt, C_uint(bcx.ccx(), count), |set_bcx, lleltptr, _| { diff --git a/src/librustc_trans/trans/type_.rs b/src/librustc_trans/trans/type_.rs index 8bff7602ddc..387af7390b2 100644 --- a/src/librustc_trans/trans/type_.rs +++ b/src/librustc_trans/trans/type_.rs @@ -31,6 +31,8 @@ pub struct Type { rf: TypeRef } +impl Copy for Type {} + macro_rules! ty ( ($e:expr) => ( Type::from_ref(unsafe { $e })) ) diff --git a/src/librustc_trans/trans/type_of.rs b/src/librustc_trans/trans/type_of.rs index 005f6ca4c70..adc919c91bf 100644 --- a/src/librustc_trans/trans/type_of.rs +++ b/src/librustc_trans/trans/type_of.rs @@ -449,12 +449,13 @@ pub enum named_ty { an_unboxed_closure, } +impl Copy for named_ty {} + pub fn llvm_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, what: named_ty, did: ast::DefId, tps: &[Ty<'tcx>]) - -> String -{ + -> String { let name = match what { a_struct => "struct", an_enum => "enum", diff --git a/src/librustc_trans/trans/value.rs b/src/librustc_trans/trans/value.rs index 33ea239412a..fa06e039023 100644 --- a/src/librustc_trans/trans/value.rs +++ b/src/librustc_trans/trans/value.rs @@ -16,6 +16,8 @@ use libc::c_uint; pub struct Value(pub ValueRef); +impl Copy for Value {} + macro_rules! opt_val ( ($e:expr) => ( unsafe { match $e { @@ -123,9 +125,14 @@ impl Value { } } +/// Wrapper for LLVM UseRef pub struct Use(UseRef); -/// Wrapper for LLVM UseRef +impl Copy for Use {} + +/** + * Wrapper for LLVM UseRef + */ impl Use { pub fn get(&self) -> UseRef { let Use(v) = *self; v @@ -148,6 +155,7 @@ impl Use { } /// Iterator for the users of a value +#[allow(missing_copy_implementations)] pub struct Users { next: Option } diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index f87a4c9294b..b6c9d8b2d21 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -52,6 +52,8 @@ pub enum CandidateSource { TraitSource(/* trait id */ ast::DefId), } +impl Copy for CandidateSource {} + type MethodIndex = uint; // just for doc purposes /// Determines whether the type `self_ty` supports a method name `method_name` or not. diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index cdf34c7f4d2..e42c9c20011 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -209,6 +209,8 @@ enum Expectation<'tcx> { ExpectCastableToType(Ty<'tcx>), } +impl<'tcx> Copy for Expectation<'tcx> {} + #[deriving(Clone)] pub struct FnStyleState { pub def: ast::NodeId, @@ -216,6 +218,8 @@ pub struct FnStyleState { from_fn: bool } +impl Copy for FnStyleState {} + impl FnStyleState { pub fn function(fn_style: ast::FnStyle, def: ast::NodeId) -> FnStyleState { FnStyleState { def: def, fn_style: fn_style, from_fn: true } @@ -2117,6 +2121,8 @@ pub enum LvaluePreference { NoPreference } +impl Copy for LvaluePreference {} + /// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide /// whether to terminate the loop. Returns the final type and number of derefs that it performed. /// @@ -2993,6 +2999,8 @@ pub enum DerefArgs { DoDerefArgs } +impl Copy for DerefArgs {} + /// Controls whether the arguments are tupled. This is used for the call /// operator. /// diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index 1769c588ec1..a011982a1fc 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -203,6 +203,11 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { } } + if fcx.tcx().lang_items.copy_trait() == Some(trait_ref.def_id) { + // This is checked in coherence. + return + } + // We are stricter on the trait-ref in an impl than the // self-type. In particular, we enforce region // relationships. The reason for this is that (at least diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 777f354bec1..48f1ef8da1d 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -354,6 +354,8 @@ enum ResolveReason { ResolvingUnboxedClosure(ast::DefId), } +impl Copy for ResolveReason {} + impl ResolveReason { fn span(&self, tcx: &ty::ctxt) -> Span { match *self { diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index b8642ddde40..578ed916541 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -18,17 +18,15 @@ use metadata::csearch::{each_impl, get_impl_trait}; use metadata::csearch; -use middle::subst; +use middle::subst::{mod, Subst}; use middle::ty::{ImplContainer, ImplOrTraitItemId, MethodTraitItemId}; -use middle::ty::{TypeTraitItemId, lookup_item_type}; -use middle::ty::{Ty, ty_bool, ty_char, ty_enum, ty_err}; -use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_open}; +use middle::ty::{ParameterEnvironment, TypeTraitItemId, lookup_item_type}; +use middle::ty::{Ty, ty_bool, ty_char, ty_closure, ty_enum, ty_err}; use middle::ty::{ty_param, Polytype, ty_ptr}; use middle::ty::{ty_rptr, ty_struct, ty_trait, ty_tup}; +use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_open}; use middle::ty::{ty_uint, ty_unboxed_closure, ty_uniq, ty_bare_fn}; -use middle::ty::{ty_closure}; -use middle::ty::type_is_ty_var; -use middle::subst::Subst; +use middle::ty::{type_is_ty_var}; use middle::ty; use CrateCtxt; use middle::infer::combine::Combine; @@ -190,6 +188,9 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { // do this here, but it's actually the most convenient place, since // the coherence tables contain the trait -> type mappings. self.populate_destructor_table(); + + // Check to make sure implementations of `Copy` are legal. + self.check_implementations_of_copy(); } fn check_implementation(&self, @@ -474,6 +475,71 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { } } } + + /// Ensures that implementations of the built-in trait `Copy` are legal. + fn check_implementations_of_copy(&self) { + let tcx = self.crate_context.tcx; + let copy_trait = match tcx.lang_items.copy_trait() { + Some(id) => id, + None => return, + }; + + let trait_impls = match tcx.trait_impls + .borrow() + .get(©_trait) + .cloned() { + None => { + debug!("check_implementations_of_copy(): no types with \ + implementations of `Copy` found"); + return + } + Some(found_impls) => found_impls + }; + + // Clone first to avoid a double borrow error. + let trait_impls = trait_impls.borrow().clone(); + + for &impl_did in trait_impls.iter() { + if impl_did.krate != ast::LOCAL_CRATE { + debug!("check_implementations_of_copy(): impl not in this \ + crate"); + continue + } + + let self_type = self.get_self_type_for_implementation(impl_did); + let span = tcx.map.span(impl_did.node); + let param_env = ParameterEnvironment::for_item(tcx, + impl_did.node); + let self_type = self_type.ty.subst(tcx, ¶m_env.free_substs); + + match ty::can_type_implement_copy(tcx, self_type, ¶m_env) { + Ok(()) => {} + Err(ty::FieldDoesNotImplementCopy(name)) => { + tcx.sess + .span_err(span, + format!("the trait `Copy` may not be \ + implemented for this type; field \ + `{}` does not implement `Copy`", + token::get_name(name)).as_slice()) + } + Err(ty::VariantDoesNotImplementCopy(name)) => { + tcx.sess + .span_err(span, + format!("the trait `Copy` may not be \ + implemented for this type; variant \ + `{}` does not implement `Copy`", + token::get_name(name)).as_slice()) + } + Err(ty::TypeIsStructural) => { + tcx.sess + .span_err(span, + "the trait `Copy` may not be implemented \ + for this type; type is not a structure or \ + enumeration") + } + } + } + } } fn subst_receiver_types_in_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 717e886029a..74ac9c480de 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -499,6 +499,8 @@ enum ConvertMethodContext<'a> { TraitConvertMethodContext(ast::DefId, &'a [ast::TraitItem]), } +impl<'a> Copy for ConvertMethodContext<'a> {} + fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>, convert_method_context: ConvertMethodContext, container: ImplOrTraitItemContainer, diff --git a/src/librustc_typeck/rscope.rs b/src/librustc_typeck/rscope.rs index 3bca24f479f..39c7a87837c 100644 --- a/src/librustc_typeck/rscope.rs +++ b/src/librustc_typeck/rscope.rs @@ -38,6 +38,8 @@ pub trait RegionScope { // for types that appear in structs and so on. pub struct ExplicitRscope; +impl Copy for ExplicitRscope {} + impl RegionScope for ExplicitRscope { fn default_region_bound(&self, _span: Span) -> Option { None @@ -77,6 +79,7 @@ impl RegionScope for UnelidableRscope { // A scope in which any omitted region defaults to `default`. This is // used after the `->` in function signatures, but also for backwards // compatibility with object types. The latter use may go away. +#[allow(missing_copy_implementations)] pub struct SpecificRscope { default: ty::Region } diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs index ade3144ce41..56f974ad665 100644 --- a/src/librustc_typeck/variance.rs +++ b/src/librustc_typeck/variance.rs @@ -232,12 +232,16 @@ type VarianceTermPtr<'a> = &'a VarianceTerm<'a>; #[deriving(Show)] struct InferredIndex(uint); +impl Copy for InferredIndex {} + enum VarianceTerm<'a> { ConstantTerm(ty::Variance), TransformTerm(VarianceTermPtr<'a>, VarianceTermPtr<'a>), InferredTerm(InferredIndex), } +impl<'a> Copy for VarianceTerm<'a> {} + impl<'a> fmt::Show for VarianceTerm<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { @@ -270,6 +274,8 @@ enum ParamKind { RegionParam } +impl Copy for ParamKind {} + struct InferredInfo<'a> { item_id: ast::NodeId, kind: ParamKind, @@ -426,6 +432,8 @@ struct Constraint<'a> { variance: &'a VarianceTerm<'a>, } +impl<'a> Copy for Constraint<'a> {} + fn add_constraints_from_crate<'a, 'tcx>(terms_cx: TermsContext<'a, 'tcx>, krate: &ast::Crate) -> ConstraintContext<'a, 'tcx> { @@ -1015,7 +1023,7 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> { while index < num_inferred && inferred_infos[index].item_id == item_id { - let info = inferred_infos[index]; + let info = &inferred_infos[index]; let variance = solutions[index]; debug!("Index {} Info {} / {} / {} Variance {}", index, info.index, info.kind, info.space, variance); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index bc870d39c5d..df7b922bd1a 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1178,6 +1178,8 @@ pub enum PrimitiveType { PrimitiveTuple, } +impl Copy for PrimitiveType {} + #[deriving(Clone, Encodable, Decodable)] pub enum TypeKind { TypeEnum, @@ -1190,6 +1192,8 @@ pub enum TypeKind { TypeTypedef, } +impl Copy for TypeKind {} + impl PrimitiveType { fn from_str(s: &str) -> Option { match s.as_slice() { @@ -1843,6 +1847,8 @@ pub enum Mutability { Immutable, } +impl Copy for Mutability {} + impl Clean for ast::Mutability { fn clean(&self, _: &DocContext) -> Mutability { match self { diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index adfd9aa8213..1aac91c4a5c 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -82,6 +82,8 @@ pub enum StructType { Unit } +impl Copy for StructType {} + pub enum TypeBound { RegionBound, TraitBound(ast::TraitRef) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 0fca59962d4..68ff2ddbcb0 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -48,6 +48,11 @@ pub struct WhereClause<'a>(pub &'a clean::Generics); /// Wrapper struct for emitting type parameter bounds. pub struct TyParamBounds<'a>(pub &'a [clean::TyParamBound]); +impl Copy for VisSpace {} +impl Copy for FnStyleSpace {} +impl Copy for MutableSpace {} +impl Copy for RawMutableSpace {} + impl VisSpace { pub fn get(&self) -> Option { let VisSpace(v) = *self; v diff --git a/src/librustdoc/html/item_type.rs b/src/librustdoc/html/item_type.rs index 0ad12b957ba..86787e5c805 100644 --- a/src/librustdoc/html/item_type.rs +++ b/src/librustdoc/html/item_type.rs @@ -41,6 +41,8 @@ pub enum ItemType { Constant = 18, } +impl Copy for ItemType {} + impl ItemType { pub fn from_item(item: &clean::Item) -> ItemType { match item.inner { diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index dab25c3b2ee..296493f3ba3 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -225,7 +225,13 @@ struct Source<'a>(&'a str); // Helper structs for rendering items/sidebars and carrying along contextual // information -struct Item<'a> { cx: &'a Context, item: &'a clean::Item, } +struct Item<'a> { + cx: &'a Context, + item: &'a clean::Item, +} + +impl<'a> Copy for Item<'a> {} + struct Sidebar<'a> { cx: &'a Context, item: &'a clean::Item, } /// Struct representing one entry in the JS search index. These are all emitted diff --git a/src/librustdoc/stability_summary.rs b/src/librustdoc/stability_summary.rs index 42f4c2a0ca6..881270afe14 100644 --- a/src/librustdoc/stability_summary.rs +++ b/src/librustdoc/stability_summary.rs @@ -39,6 +39,8 @@ pub struct Counts { pub unmarked: uint, } +impl Copy for Counts {} + impl Add for Counts { fn add(&self, other: &Counts) -> Counts { Counts { diff --git a/src/librustrt/bookkeeping.rs b/src/librustrt/bookkeeping.rs index 714bbd569bd..e918a496d55 100644 --- a/src/librustrt/bookkeeping.rs +++ b/src/librustrt/bookkeeping.rs @@ -26,6 +26,7 @@ use mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT}; static TASK_COUNT: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT; static TASK_LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT; +#[allow(missing_copy_implementations)] pub struct Token { _private: () } impl Drop for Token { diff --git a/src/librustrt/c_str.rs b/src/librustrt/c_str.rs index 261bd1b9f8c..07094f08c5d 100644 --- a/src/librustrt/c_str.rs +++ b/src/librustrt/c_str.rs @@ -85,6 +85,7 @@ use libc; /// /// This structure wraps a `*libc::c_char`, and will automatically free the /// memory it is pointing to when it goes out of scope. +#[allow(missing_copy_implementations)] pub struct CString { buf: *const libc::c_char, owns_buffer_: bool, diff --git a/src/librustrt/mutex.rs b/src/librustrt/mutex.rs index 2f0daf8f6e2..5b58ec8fd3a 100644 --- a/src/librustrt/mutex.rs +++ b/src/librustrt/mutex.rs @@ -361,6 +361,7 @@ mod imp { #[cfg(any(target_os = "macos", target_os = "ios"))] mod os { + use core::kinds::Copy; use libc; #[cfg(target_arch = "x86_64")] @@ -384,12 +385,17 @@ mod imp { __sig: libc::c_long, __opaque: [u8, ..__PTHREAD_MUTEX_SIZE__], } + + impl Copy for pthread_mutex_t {} + #[repr(C)] pub struct pthread_cond_t { __sig: libc::c_long, __opaque: [u8, ..__PTHREAD_COND_SIZE__], } + impl Copy for pthread_cond_t {} + pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { __sig: _PTHREAD_MUTEX_SIG_INIT, __opaque: [0, ..__PTHREAD_MUTEX_SIZE__], @@ -402,6 +408,7 @@ mod imp { #[cfg(target_os = "linux")] mod os { + use core::kinds::Copy; use libc; // minus 8 because we have an 'align' field @@ -431,12 +438,17 @@ mod imp { __align: libc::c_longlong, size: [u8, ..__SIZEOF_PTHREAD_MUTEX_T], } + + impl Copy for pthread_mutex_t {} + #[repr(C)] pub struct pthread_cond_t { __align: libc::c_longlong, size: [u8, ..__SIZEOF_PTHREAD_COND_T], } + impl Copy for pthread_cond_t {} + pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { __align: 0, size: [0, ..__SIZEOF_PTHREAD_MUTEX_T], diff --git a/src/librustrt/unwind.rs b/src/librustrt/unwind.rs index 697ee95df4c..714d30ae4b1 100644 --- a/src/librustrt/unwind.rs +++ b/src/librustrt/unwind.rs @@ -77,6 +77,7 @@ use task::Task; use libunwind as uw; +#[allow(missing_copy_implementations)] pub struct Unwinder { unwinding: bool, } diff --git a/src/librustrt/util.rs b/src/librustrt/util.rs index c77fbd4aee0..fd30c3a48d2 100644 --- a/src/librustrt/util.rs +++ b/src/librustrt/util.rs @@ -29,6 +29,9 @@ pub const ENFORCE_SANITY: bool = true || !cfg!(rtopt) || cfg!(rtdebug) || pub struct Stdio(libc::c_int); #[allow(non_upper_case_globals)] +impl Copy for Stdio {} + +#[allow(non_uppercase_statics)] pub const Stdout: Stdio = Stdio(libc::STDOUT_FILENO); #[allow(non_upper_case_globals)] pub const Stderr: Stdio = Stdio(libc::STDERR_FILENO); diff --git a/src/libserialize/base64.rs b/src/libserialize/base64.rs index c8ec1700a1d..dd5039c9b82 100644 --- a/src/libserialize/base64.rs +++ b/src/libserialize/base64.rs @@ -26,6 +26,8 @@ pub enum CharacterSet { UrlSafe } +impl Copy for CharacterSet {} + /// Contains configuration parameters for `to_base64`. pub struct Config { /// Character set to use @@ -36,6 +38,8 @@ pub struct Config { pub line_length: Option } +impl Copy for Config {} + /// Configuration for RFC 4648 standard base64 encoding pub static STANDARD: Config = Config {char_set: Standard, pad: true, line_length: None}; @@ -168,6 +172,8 @@ pub enum FromBase64Error { InvalidBase64Length, } +impl Copy for FromBase64Error {} + impl fmt::Show for FromBase64Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { diff --git a/src/libserialize/hex.rs b/src/libserialize/hex.rs index 4c20f72cac5..22392056ddf 100644 --- a/src/libserialize/hex.rs +++ b/src/libserialize/hex.rs @@ -68,6 +68,8 @@ pub enum FromHexError { InvalidHexLength, } +impl Copy for FromHexError {} + impl fmt::Show for FromHexError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 248d78236ad..318c21234f5 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -247,6 +247,8 @@ pub enum ErrorCode { NotUtf8, } +impl Copy for ErrorCode {} + #[deriving(Clone, PartialEq, Show)] pub enum ParserError { /// msg, line, col @@ -254,6 +256,8 @@ pub enum ParserError { IoError(io::IoErrorKind, &'static str), } +impl Copy for ParserError {} + // Builder and Parser have the same errors. pub type BuilderError = ParserError; diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index 2872f74cf88..23eb367dbd1 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -18,6 +18,7 @@ use core::kinds::Sized; use fmt; use iter::IteratorExt; +use kinds::Copy; use mem; use option::Option; use option::Option::{Some, None}; @@ -30,6 +31,8 @@ use vec::Vec; #[deriving(Clone, PartialEq, PartialOrd, Ord, Eq, Hash)] pub struct Ascii { chr: u8 } +impl Copy for Ascii {} + impl Ascii { /// Converts an ascii character into a `u8`. #[inline] diff --git a/src/libstd/bitflags.rs b/src/libstd/bitflags.rs index 8a90c06f038..ffcd6505dad 100644 --- a/src/libstd/bitflags.rs +++ b/src/libstd/bitflags.rs @@ -33,6 +33,8 @@ /// } /// } /// +/// impl Copy for Flags {} +/// /// fn main() { /// let e1 = FLAG_A | FLAG_C; /// let e2 = FLAG_B | FLAG_C; @@ -55,6 +57,8 @@ /// } /// } /// +/// impl Copy for Flags {} +/// /// impl Flags { /// pub fn clear(&mut self) { /// self.bits = 0; // The `bits` field can be accessed from within the @@ -260,6 +264,7 @@ macro_rules! bitflags { #[cfg(test)] #[allow(non_upper_case_globals)] mod tests { + use kinds::Copy; use hash; use option::Option::{Some, None}; use ops::{BitOr, BitAnd, BitXor, Sub, Not}; @@ -283,12 +288,16 @@ mod tests { } } + impl Copy for Flags {} + bitflags! { flags AnotherSetOfFlags: i8 { const AnotherFlag = -1_i8, } } + impl Copy for AnotherSetOfFlags {} + #[test] fn test_bits(){ assert_eq!(Flags::empty().bits(), 0x00000000); diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index de06a1e0bbd..ef4cabedc47 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -16,7 +16,7 @@ use clone::Clone; use cmp; use hash::{Hash, Hasher}; use iter::{Iterator, count}; -use kinds::{Sized, marker}; +use kinds::{Copy, Sized, marker}; use mem::{min_align_of, size_of}; use mem; use num::{Int, UnsignedInt}; @@ -81,12 +81,16 @@ struct RawBucket { val: *mut V } +impl Copy for RawBucket {} + pub struct Bucket { raw: RawBucket, idx: uint, table: M } +impl Copy for Bucket {} + pub struct EmptyBucket { raw: RawBucket, idx: uint, diff --git a/src/libstd/comm/mod.rs b/src/libstd/comm/mod.rs index d291ed72567..6cff5a3dd23 100644 --- a/src/libstd/comm/mod.rs +++ b/src/libstd/comm/mod.rs @@ -405,6 +405,8 @@ pub enum TryRecvError { Disconnected, } +impl Copy for TryRecvError {} + /// This enumeration is the list of the possible error outcomes for the /// `SyncSender::try_send` method. #[deriving(PartialEq, Clone, Show)] diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs index aa0c8b53c2e..5609fbf16cd 100644 --- a/src/libstd/dynamic_lib.rs +++ b/src/libstd/dynamic_lib.rs @@ -29,7 +29,10 @@ use str; use string::String; use vec::Vec; -pub struct DynamicLibrary { handle: *mut u8 } +#[allow(missing_copy_implementations)] +pub struct DynamicLibrary { + handle: *mut u8 +} impl Drop for DynamicLibrary { fn drop(&mut self) { @@ -210,6 +213,7 @@ pub mod dl { use c_str::{CString, ToCStr}; use libc; + use kinds::Copy; use ptr; use result::*; use string::String; @@ -262,6 +266,8 @@ pub mod dl { Local = 0, } + impl Copy for Rtld {} + #[link_name = "dl"] extern { fn dlopen(filename: *const libc::c_char, diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index d43a7a66c5b..dc212e7cab3 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -231,6 +231,7 @@ use error::{FromError, Error}; use fmt; use int; use iter::{Iterator, IteratorExt}; +use kinds::Copy; use mem::transmute; use ops::{BitOr, BitXor, BitAnd, Sub, Not}; use option::Option; @@ -420,6 +421,8 @@ pub enum IoErrorKind { NoProgress, } +impl Copy for IoErrorKind {} + /// A trait that lets you add a `detail` to an IoError easily trait UpdateIoError { /// Returns an IoError with updated description and detail @@ -1560,6 +1563,8 @@ pub enum SeekStyle { SeekCur, } +impl Copy for SeekStyle {} + /// An object implementing `Seek` internally has some form of cursor which can /// be moved within a stream of bytes. The stream typically has a fixed size, /// allowing seeking relative to either end. @@ -1682,6 +1687,8 @@ pub enum FileMode { Truncate, } +impl Copy for FileMode {} + /// Access permissions with which the file should be opened. `File`s /// opened with `Read` will return an error if written to. pub enum FileAccess { @@ -1693,6 +1700,8 @@ pub enum FileAccess { ReadWrite, } +impl Copy for FileAccess {} + /// Different kinds of files which can be identified by a call to stat #[deriving(PartialEq, Show, Hash, Clone)] pub enum FileType { @@ -1715,6 +1724,8 @@ pub enum FileType { Unknown, } +impl Copy for FileType {} + /// A structure used to describe metadata information about a file. This /// structure is created through the `stat` method on a `Path`. /// @@ -1766,6 +1777,8 @@ pub struct FileStat { pub unstable: UnstableFileStat, } +impl Copy for FileStat {} + /// This structure represents all of the possible information which can be /// returned from a `stat` syscall which is not contained in the `FileStat` /// structure. This information is not necessarily platform independent, and may @@ -1795,6 +1808,8 @@ pub struct UnstableFileStat { pub gen: u64, } +impl Copy for UnstableFileStat {} + bitflags! { #[doc = "A set of permissions for a file or directory is represented"] #[doc = "by a set of flags which are or'd together."] @@ -1889,6 +1904,8 @@ bitflags! { } } +impl Copy for FilePermission {} + impl Default for FilePermission { #[inline] fn default() -> FilePermission { FilePermission::empty() } diff --git a/src/libstd/io/net/addrinfo.rs b/src/libstd/io/net/addrinfo.rs index fea8372733c..fc81ab7b57a 100644 --- a/src/libstd/io/net/addrinfo.rs +++ b/src/libstd/io/net/addrinfo.rs @@ -22,6 +22,7 @@ pub use self::Protocol::*; use iter::IteratorExt; use io::{IoResult}; use io::net::ip::{SocketAddr, IpAddr}; +use kinds::Copy; use option::Option; use option::Option::{Some, None}; use sys; @@ -32,6 +33,8 @@ pub enum SocketType { Stream, Datagram, Raw } +impl Copy for SocketType {} + /// Flags which can be or'd into the `flags` field of a `Hint`. These are used /// to manipulate how a query is performed. /// @@ -46,12 +49,16 @@ pub enum Flag { V4Mapped, } +impl Copy for Flag {} + /// A transport protocol associated with either a hint or a return value of /// `lookup` pub enum Protocol { TCP, UDP } +impl Copy for Protocol {} + /// This structure is used to provide hints when fetching addresses for a /// remote host to control how the lookup is performed. /// @@ -64,6 +71,8 @@ pub struct Hint { pub flags: uint, } +impl Copy for Hint {} + pub struct Info { pub address: SocketAddr, pub family: uint, @@ -72,6 +81,8 @@ pub struct Info { pub flags: uint, } +impl Copy for Info {} + /// Easy name resolution. Given a hostname, returns the list of IP addresses for /// that hostname. pub fn get_host_addresses(host: &str) -> IoResult> { diff --git a/src/libstd/io/net/ip.rs b/src/libstd/io/net/ip.rs index 3fa6f4a6091..f59dd37c0da 100644 --- a/src/libstd/io/net/ip.rs +++ b/src/libstd/io/net/ip.rs @@ -18,6 +18,7 @@ pub use self::IpAddr::*; use fmt; +use kinds::Copy; use io::{mod, IoResult, IoError}; use io::net; use iter::{Iterator, IteratorExt}; @@ -36,6 +37,8 @@ pub enum IpAddr { Ipv6Addr(u16, u16, u16, u16, u16, u16, u16, u16) } +impl Copy for IpAddr {} + impl fmt::Show for IpAddr { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { match *self { @@ -67,6 +70,8 @@ pub struct SocketAddr { pub port: Port, } +impl Copy for SocketAddr {} + impl fmt::Show for SocketAddr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.ip { diff --git a/src/libstd/io/process.rs b/src/libstd/io/process.rs index 61ebfb06c71..c46a6e82e44 100644 --- a/src/libstd/io/process.rs +++ b/src/libstd/io/process.rs @@ -480,6 +480,8 @@ pub enum StdioContainer { CreatePipe(bool /* readable */, bool /* writable */), } +impl Copy for StdioContainer {} + /// Describes the result of a process after it has terminated. /// Note that Windows have no signals, so the result is usually ExitStatus. #[deriving(PartialEq, Eq, Clone)] @@ -491,6 +493,8 @@ pub enum ProcessExit { ExitSignal(int), } +impl Copy for ProcessExit {} + impl fmt::Show for ProcessExit { /// Format a ProcessExit enum, to nicely present the information. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs index e78bd1dd33f..faa52226a03 100644 --- a/src/libstd/io/util.rs +++ b/src/libstd/io/util.rs @@ -83,6 +83,8 @@ impl Buffer for LimitReader { /// A `Writer` which ignores bytes written to it, like /dev/null. pub struct NullWriter; +impl Copy for NullWriter {} + impl Writer for NullWriter { #[inline] fn write(&mut self, _buf: &[u8]) -> io::IoResult<()> { Ok(()) } @@ -91,6 +93,8 @@ impl Writer for NullWriter { /// A `Reader` which returns an infinite stream of 0 bytes, like /dev/zero. pub struct ZeroReader; +impl Copy for ZeroReader {} + impl Reader for ZeroReader { #[inline] fn read(&mut self, buf: &mut [u8]) -> io::IoResult { @@ -111,6 +115,8 @@ impl Buffer for ZeroReader { /// A `Reader` which is always at EOF, like /dev/null. pub struct NullReader; +impl Copy for NullReader {} + impl Reader for NullReader { #[inline] fn read(&mut self, _buf: &mut [u8]) -> io::IoResult { diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index c87f40f351b..1c9826ff5ac 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -18,6 +18,7 @@ pub use self::SignFormat::*; use char; use char::Char; +use kinds::Copy; use num; use num::{Int, Float, FPNaN, FPInfinite, ToPrimitive}; use slice::{SlicePrelude, CloneSliceAllocPrelude}; @@ -38,6 +39,8 @@ pub enum ExponentFormat { ExpBin, } +impl Copy for ExponentFormat {} + /// The number of digits used for emitting the fractional part of a number, if /// any. pub enum SignificantDigits { @@ -55,6 +58,8 @@ pub enum SignificantDigits { DigExact(uint) } +impl Copy for SignificantDigits {} + /// How to emit the sign of a number. pub enum SignFormat { /// No sign will be printed. The exponent sign will also be emitted. @@ -67,25 +72,33 @@ pub enum SignFormat { SignAll, } -/// Converts an integral number to its string representation as a byte vector. -/// This is meant to be a common base implementation for all integral string -/// conversion functions like `to_string()` or `to_str_radix()`. -/// -/// # Arguments -/// -/// - `num` - The number to convert. Accepts any number that -/// implements the numeric traits. -/// - `radix` - Base to use. Accepts only the values 2-36. -/// - `sign` - How to emit the sign. Options are: -/// - `SignNone`: No sign at all. Basically emits `abs(num)`. -/// - `SignNeg`: Only `-` on negative values. -/// - `SignAll`: Both `+` on positive, and `-` on negative numbers. -/// - `f` - a callback which will be invoked for each ascii character -/// which composes the string representation of this integer -/// -/// # Panics -/// -/// - Panics if `radix` < 2 or `radix` > 36. +impl Copy for SignFormat {} + +/** + * Converts an integral number to its string representation as a byte vector. + * This is meant to be a common base implementation for all integral string + * conversion functions like `to_string()` or `to_str_radix()`. + * + * # Arguments + * - `num` - The number to convert. Accepts any number that + * implements the numeric traits. + * - `radix` - Base to use. Accepts only the values 2-36. + * - `sign` - How to emit the sign. Options are: + * - `SignNone`: No sign at all. Basically emits `abs(num)`. + * - `SignNeg`: Only `-` on negative values. + * - `SignAll`: Both `+` on positive, and `-` on negative numbers. + * - `f` - a callback which will be invoked for each ascii character + * which composes the string representation of this integer + * + * # Return value + * A tuple containing the byte vector, and a boolean flag indicating + * whether it represents a special value like `inf`, `-inf`, `NaN` or not. + * It returns a tuple because there can be ambiguity between a special value + * and a number representation at higher bases. + * + * # Failure + * - Fails if `radix` < 2 or `radix` > 36. + */ fn int_to_str_bytes_common(num: T, radix: uint, sign: SignFormat, f: |u8|) { assert!(2 <= radix && radix <= 36); diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 2b904acb565..f298ec74f6a 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -36,6 +36,7 @@ use error::{FromError, Error}; use fmt; use io::{IoResult, IoError}; use iter::{Iterator, IteratorExt}; +use kinds::Copy; use libc::{c_void, c_int}; use libc; use boxed::Box; @@ -619,6 +620,8 @@ pub struct Pipe { pub writer: c_int, } +impl Copy for Pipe {} + /// Creates a new low-level OS in-memory pipe. /// /// This function can fail to succeed if there are no more resources available @@ -1185,6 +1188,9 @@ pub struct MemoryMap { kind: MemoryMapKind, } +#[cfg(not(stage0))] +impl Copy for MemoryMap {} + /// Type of memory map pub enum MemoryMapKind { /// Virtual memory map. Usually used to change the permissions of a given @@ -1196,6 +1202,8 @@ pub enum MemoryMapKind { MapVirtual } +impl Copy for MemoryMapKind {} + /// Options the memory map is created with pub enum MapOption { /// The memory should be readable @@ -1219,6 +1227,8 @@ pub enum MapOption { MapNonStandardFlags(c_int), } +impl Copy for MapOption {} + /// Possible errors when creating a map. pub enum MapError { /// ## The following are POSIX-specific @@ -1264,6 +1274,8 @@ pub enum MapError { ErrMapViewOfFile(uint) } +impl Copy for MapError {} + impl fmt::Show for MapError { fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result { let str = match *self { diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index b53e6b2a5e0..ea522536d22 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -22,6 +22,7 @@ use hash; use io::Writer; use iter::{AdditiveIterator, DoubleEndedIteratorExt, Extend}; use iter::{Iterator, IteratorExt, Map}; +use kinds::Copy; use mem; use option::Option; use option::Option::{Some, None}; @@ -985,6 +986,8 @@ pub enum PathPrefix { DiskPrefix } +impl Copy for PathPrefix {} + fn parse_prefix<'a>(mut path: &'a str) -> Option { if path.starts_with("\\\\") { // \\ diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs index cc3c46f3610..a359fcf7a9f 100644 --- a/src/libstd/rand/mod.rs +++ b/src/libstd/rand/mod.rs @@ -225,6 +225,7 @@ use cell::RefCell; use clone::Clone; use io::IoResult; use iter::{Iterator, IteratorExt}; +use kinds::Copy; use mem; use rc::Rc; use result::Result::{Ok, Err}; @@ -245,7 +246,11 @@ pub mod reader; /// The standard RNG. This is designed to be efficient on the current /// platform. -pub struct StdRng { rng: IsaacWordRng } +pub struct StdRng { + rng: IsaacWordRng, +} + +impl Copy for StdRng {} impl StdRng { /// Create a randomly seeded instance of `StdRng`. diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs index 86c3a1fdd32..7e6065129a3 100644 --- a/src/libstd/time/duration.rs +++ b/src/libstd/time/duration.rs @@ -13,6 +13,7 @@ #![experimental] use {fmt, i64}; +use kinds::Copy; use ops::{Add, Sub, Mul, Div, Neg}; use option::Option; use option::Option::{Some, None}; @@ -64,6 +65,8 @@ pub const MAX: Duration = Duration { nanos: (i64::MAX % MILLIS_PER_SEC) as i32 * NANOS_PER_MILLI }; +impl Copy for Duration {} + impl Duration { /// Makes a new `Duration` with given number of weeks. /// Equivalent to `Duration::seconds(weeks * 7 * 24 * 60 * 60), with overflow checks. diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs index 87693f39bbd..71d29bca401 100644 --- a/src/libsyntax/abi.rs +++ b/src/libsyntax/abi.rs @@ -16,8 +16,17 @@ pub use self::AbiArchitecture::*; use std::fmt; #[deriving(PartialEq)] -pub enum Os { OsWindows, OsMacos, OsLinux, OsAndroid, OsFreebsd, OsiOS, - OsDragonfly } +pub enum Os { + OsWindows, + OsMacos, + OsLinux, + OsAndroid, + OsFreebsd, + OsiOS, + OsDragonfly, +} + +impl Copy for Os {} #[deriving(PartialEq, Eq, Hash, Encodable, Decodable, Clone)] pub enum Abi { @@ -39,6 +48,8 @@ pub enum Abi { RustCall, } +impl Copy for Abi {} + #[allow(non_camel_case_types)] #[deriving(PartialEq)] pub enum Architecture { @@ -49,6 +60,8 @@ pub enum Architecture { Mipsel } +impl Copy for Architecture {} + pub struct AbiData { abi: Abi, @@ -56,6 +69,8 @@ pub struct AbiData { name: &'static str, } +impl Copy for AbiData {} + pub enum AbiArchitecture { /// Not a real ABI (e.g., intrinsic) RustArch, @@ -65,6 +80,9 @@ pub enum AbiArchitecture { Archs(u32) } +#[allow(non_upper_case_globals)] +impl Copy for AbiArchitecture {} + #[allow(non_upper_case_globals)] static AbiDatas: &'static [AbiData] = &[ // Platform-specific ABIs diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 7e421df505d..0a04a953b31 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -86,6 +86,8 @@ pub struct Ident { pub ctxt: SyntaxContext } +impl Copy for Ident {} + impl Ident { /// Construct an identifier with the given name and an empty context: pub fn new(name: Name) -> Ident { Ident {name: name, ctxt: EMPTY_CTXT}} @@ -161,6 +163,8 @@ pub const ILLEGAL_CTXT : SyntaxContext = 1; #[deriving(Eq, Ord, PartialEq, PartialOrd, Hash, Encodable, Decodable, Clone)] pub struct Name(pub u32); +impl Copy for Name {} + impl Name { pub fn as_str<'a>(&'a self) -> &'a str { unsafe { @@ -204,6 +208,8 @@ pub struct Lifetime { pub name: Name } +impl Copy for Lifetime {} + #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub struct LifetimeDef { pub lifetime: Lifetime, @@ -338,6 +344,8 @@ pub struct DefId { pub node: NodeId, } +impl Copy for DefId {} + /// Item definitions in the currently-compiled crate would have the CrateNum /// LOCAL_CRATE in their DefId. pub const LOCAL_CRATE: CrateNum = 0; @@ -482,6 +490,8 @@ pub enum BindingMode { BindByValue(Mutability), } +impl Copy for BindingMode {} + #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum PatWildKind { /// Represents the wildcard pattern `_` @@ -491,6 +501,8 @@ pub enum PatWildKind { PatWildMulti, } +impl Copy for PatWildKind {} + #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum Pat_ { /// Represents a wildcard pattern (either `_` or `..`) @@ -526,6 +538,8 @@ pub enum Mutability { MutImmutable, } +impl Copy for Mutability {} + #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum BinOp { BiAdd, @@ -548,6 +562,9 @@ pub enum BinOp { BiGt, } +#[cfg(not(stage0))] +impl Copy for BinOp {} + #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum UnOp { UnUniq, @@ -556,6 +573,8 @@ pub enum UnOp { UnNeg } +impl Copy for UnOp {} + pub type Stmt = Spanned; #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] @@ -581,6 +600,8 @@ pub enum LocalSource { LocalFor, } +impl Copy for LocalSource {} + // FIXME (pending discussion of #1697, #2178...): local should really be // a refinement on pat. /// Local represents a `let` statement, e.g., `let : = ;` @@ -628,12 +649,16 @@ pub enum BlockCheckMode { UnsafeBlock(UnsafeSource), } +impl Copy for BlockCheckMode {} + #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum UnsafeSource { CompilerGenerated, UserProvided, } +impl Copy for UnsafeSource {} + #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub struct Expr { pub id: NodeId, @@ -718,12 +743,16 @@ pub enum MatchSource { MatchWhileLetDesugar, } +impl Copy for MatchSource {} + #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum CaptureClause { CaptureByValue, CaptureByRef, } +impl Copy for CaptureClause {} + /// A delimited sequence of token trees #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub struct Delimited { @@ -780,6 +809,8 @@ pub enum KleeneOp { OneOrMore, } +impl Copy for KleeneOp {} + /// When the main rust parser encounters a syntax-extension invocation, it /// parses the arguments to the invocation as a token-tree. This is a very /// loose structure, such that all sorts of different AST-fragments can @@ -895,6 +926,8 @@ pub enum StrStyle { RawStr(uint) } +impl Copy for StrStyle {} + pub type Lit = Spanned; #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] @@ -903,7 +936,9 @@ pub enum Sign { Plus } -impl Sign { +impl Copy for Sign {} + +impl Sign where T: Int { pub fn new(n: T) -> Sign { if n < Int::zero() { Minus @@ -920,6 +955,8 @@ pub enum LitIntType { UnsuffixedIntLit(Sign) } +impl Copy for LitIntType {} + impl LitIntType { pub fn suffix_len(&self) -> uint { match *self { @@ -1015,6 +1052,8 @@ pub enum IntTy { TyI64, } +impl Copy for IntTy {} + impl fmt::Show for IntTy { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", ast_util::int_ty_to_string(*self, None)) @@ -1040,6 +1079,8 @@ pub enum UintTy { TyU64, } +impl Copy for UintTy {} + impl UintTy { pub fn suffix_len(&self) -> uint { match *self { @@ -1062,6 +1103,8 @@ pub enum FloatTy { TyF64, } +impl Copy for FloatTy {} + impl fmt::Show for FloatTy { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", ast_util::float_ty_to_string(*self)) @@ -1095,12 +1138,16 @@ pub enum PrimTy { TyChar } +impl Copy for PrimTy {} + #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] pub enum Onceness { Once, Many } +impl Copy for Onceness {} + impl fmt::Show for Onceness { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { @@ -1171,6 +1218,8 @@ pub enum AsmDialect { AsmIntel } +impl Copy for AsmDialect {} + #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub struct InlineAsm { pub asm: InternedString, @@ -1228,6 +1277,8 @@ pub enum FnStyle { NormalFn, } +impl Copy for FnStyle {} + impl fmt::Show for FnStyle { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { @@ -1345,6 +1396,8 @@ pub enum PathListItem_ { PathListMod { id: NodeId } } +impl Copy for PathListItem_ {} + impl PathListItem_ { pub fn id(&self) -> NodeId { match *self { @@ -1404,9 +1457,13 @@ pub enum AttrStyle { AttrInner, } +impl Copy for AttrStyle {} + #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub struct AttrId(pub uint); +impl Copy for AttrId {} + /// Doc-comments are promoted to attributes that have is_sugared_doc = true #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub struct Attribute_ { @@ -1442,6 +1499,8 @@ pub enum Visibility { Inherited, } +impl Copy for Visibility {} + impl Visibility { pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility { match self { @@ -1477,6 +1536,8 @@ pub enum StructFieldKind { UnnamedField(Visibility), } +impl Copy for StructFieldKind {} + impl StructFieldKind { pub fn is_unnamed(&self) -> bool { match *self { @@ -1583,6 +1644,8 @@ pub enum UnboxedClosureKind { FnOnceUnboxedClosureKind, } +impl Copy for UnboxedClosureKind {} + /// The data we save and restore about an inlined item or method. This is not /// part of the AST that we parse from a file, but it becomes part of the tree /// that we trans. diff --git a/src/libsyntax/ast_map/blocks.rs b/src/libsyntax/ast_map/blocks.rs index 8db12fbd835..639a33a8063 100644 --- a/src/libsyntax/ast_map/blocks.rs +++ b/src/libsyntax/ast_map/blocks.rs @@ -43,6 +43,8 @@ use visit; /// To construct one, use the `Code::from_node` function. pub struct FnLikeNode<'a> { node: ast_map::Node<'a> } +impl<'a> Copy for FnLikeNode<'a> {} + /// MaybeFnLike wraps a method that indicates if an object /// corresponds to some FnLikeNode. pub trait MaybeFnLike { fn is_fn_like(&self) -> bool; } @@ -85,6 +87,8 @@ pub enum Code<'a> { BlockCode(&'a Block), } +impl<'a> Copy for Code<'a> {} + impl<'a> Code<'a> { pub fn id(&self) -> ast::NodeId { match *self { diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs index ce2fe6e7220..2c985f403f8 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -38,6 +38,8 @@ pub enum PathElem { PathName(Name) } +impl Copy for PathElem {} + impl PathElem { pub fn name(&self) -> Name { match *self { @@ -120,6 +122,8 @@ pub enum Node<'ast> { NodeLifetime(&'ast Lifetime), } +impl<'ast> Copy for Node<'ast> {} + /// Represents an entry and its parent Node ID /// The odd layout is to bring down the total size. #[deriving(Show)] @@ -147,6 +151,8 @@ enum MapEntry<'ast> { RootInlinedParent(&'ast InlinedParent) } +impl<'ast> Copy for MapEntry<'ast> {} + impl<'ast> Clone for MapEntry<'ast> { fn clone(&self) -> MapEntry<'ast> { *self diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 68bb7ecfb85..7dba6a57fc4 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -315,6 +315,8 @@ pub struct IdRange { pub max: NodeId, } +impl Copy for IdRange {} + impl IdRange { pub fn max() -> IdRange { IdRange { diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index a2811681efd..5894a88ece6 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -282,6 +282,8 @@ pub enum InlineAttr { InlineNever, } +impl Copy for InlineAttr {} + /// Determine what `#[inline]` attribute is present in `attrs`, if any. pub fn find_inline_attr(attrs: &[Attribute]) -> InlineAttr { // FIXME (#2809)---validate the usage of #[inline] and #[inline] @@ -354,6 +356,8 @@ pub enum StabilityLevel { Locked } +impl Copy for StabilityLevel {} + pub fn find_stability_generic<'a, AM: AttrMetaMethods, I: Iterator<&'a AM>> @@ -469,6 +473,8 @@ pub enum ReprAttr { ReprPacked, } +impl Copy for ReprAttr {} + impl ReprAttr { pub fn is_ffi_safe(&self) -> bool { match *self { @@ -486,6 +492,8 @@ pub enum IntType { UnsignedInt(ast::UintTy) } +impl Copy for IntType {} + impl IntType { #[inline] pub fn is_signed(self) -> bool { diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 6bcf562204b..50b4f342368 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -34,12 +34,16 @@ pub trait Pos { #[deriving(Clone, PartialEq, Eq, Hash, PartialOrd, Show)] pub struct BytePos(pub u32); +impl Copy for BytePos {} + /// A character offset. Because of multibyte utf8 characters, a byte offset /// is not equivalent to a character offset. The CodeMap will convert BytePos /// values to CharPos values as necessary. #[deriving(PartialEq, Hash, PartialOrd, Show)] pub struct CharPos(pub uint); +impl Copy for CharPos {} + // FIXME: Lots of boilerplate in these impls, but so far my attempts to fix // have been unsuccessful @@ -90,6 +94,8 @@ pub struct Span { pub expn_id: ExpnId } +impl Copy for Span {} + pub const DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0), expn_id: NO_EXPANSION }; #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] @@ -98,6 +104,8 @@ pub struct Spanned { pub span: Span, } +impl Copy for Spanned {} + impl PartialEq for Span { fn eq(&self, other: &Span) -> bool { return (*self).lo == (*other).lo && (*self).hi == (*other).hi; @@ -183,6 +191,8 @@ pub enum MacroFormat { MacroBang } +impl Copy for MacroFormat {} + #[deriving(Clone, Hash, Show)] pub struct NameAndSpan { /// The name of the macro that was invoked to create the thing @@ -221,6 +231,8 @@ pub struct ExpnInfo { #[deriving(PartialEq, Eq, Clone, Show, Hash, Encodable, Decodable)] pub struct ExpnId(u32); +impl Copy for ExpnId {} + pub const NO_EXPANSION: ExpnId = ExpnId(-1); impl ExpnId { @@ -249,6 +261,8 @@ pub struct MultiByteChar { pub bytes: uint, } +impl Copy for MultiByteChar {} + /// A single source in the CodeMap pub struct FileMap { /// The name of the file that the source came from, source that doesn't diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 293c1b3a953..bbda80bd96c 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -40,6 +40,8 @@ pub enum RenderSpan { FileLine(Span), } +impl Copy for RenderSpan {} + impl RenderSpan { fn span(self) -> Span { match self { @@ -61,6 +63,8 @@ pub enum ColorConfig { Never } +impl Copy for ColorConfig {} + pub trait Emitter { fn emit(&mut self, cmsp: Option<(&codemap::CodeMap, Span)>, msg: &str, code: Option<&str>, lvl: Level); @@ -73,10 +77,14 @@ pub trait Emitter { /// how a rustc task died (if so desired). pub struct FatalError; +impl Copy for FatalError {} + /// Signifies that the compiler died with an explicit call to `.bug` /// or `.span_bug` rather than a failed assertion, etc. pub struct ExplicitBug; +impl Copy for ExplicitBug {} + /// A span-handler is like a handler but also /// accepts span information for source-location /// reporting. @@ -230,6 +238,8 @@ pub enum Level { Help, } +impl Copy for Level {} + impl fmt::Show for Level { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use std::fmt::Show; diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 0787518f04f..3c7a4a81d20 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -57,7 +57,7 @@ impl ItemDecorator for fn(&mut ExtCtxt, Span, &ast::MetaItem, &ast::Item, |P|) { - (*self)(ecx, sp, meta_item, item, push) + self.clone()(ecx, sp, meta_item, item, push) } } @@ -77,7 +77,7 @@ impl ItemModifier for fn(&mut ExtCtxt, Span, &ast::MetaItem, P) -> P< meta_item: &ast::MetaItem, item: P) -> P { - (*self)(ecx, span, meta_item, item) + self.clone()(ecx, span, meta_item, item) } } @@ -99,7 +99,7 @@ impl TTMacroExpander for MacroExpanderFn { span: Span, token_tree: &[ast::TokenTree]) -> Box { - (*self)(ecx, span, token_tree) + self.clone()(ecx, span, token_tree) } } @@ -122,7 +122,7 @@ impl IdentMacroExpander for IdentMacroExpanderFn { ident: ast::Ident, token_tree: Vec ) -> Box { - (*self)(cx, sp, ident, token_tree) + self.clone()(cx, sp, ident, token_tree) } } @@ -228,6 +228,8 @@ pub struct DummyResult { span: Span } +impl Copy for DummyResult {} + impl DummyResult { /// Create a default MacResult that can be anything. /// diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs index 787c6e844d5..1bd55b5d504 100644 --- a/src/libsyntax/ext/deriving/cmp/ord.rs +++ b/src/libsyntax/ext/deriving/cmp/ord.rs @@ -85,6 +85,8 @@ pub enum OrderingOp { PartialCmpOp, LtOp, LeOp, GtOp, GeOp, } +impl Copy for OrderingOp {} + pub fn some_ordering_collapsed(cx: &mut ExtCtxt, span: Span, op: OrderingOp, diff --git a/src/libsyntax/ext/mtwt.rs b/src/libsyntax/ext/mtwt.rs index 6ba90bbebed..48120b575ac 100644 --- a/src/libsyntax/ext/mtwt.rs +++ b/src/libsyntax/ext/mtwt.rs @@ -56,6 +56,8 @@ pub enum SyntaxContext_ { IllegalCtxt } +impl Copy for SyntaxContext_ {} + /// A list of ident->name renamings pub type RenameList = Vec<(Ident, Name)>; diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 4af7b35079a..ac36e508f3b 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -103,6 +103,8 @@ pub struct Features { pub quote: bool, } +impl Copy for Features {} + impl Features { pub fn new() -> Features { Features { diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/parse/lexer/comments.rs index aeec6ee13fd..a17d66476c0 100644 --- a/src/libsyntax/parse/lexer/comments.rs +++ b/src/libsyntax/parse/lexer/comments.rs @@ -36,6 +36,8 @@ pub enum CommentStyle { BlankLine, } +impl Copy for CommentStyle {} + #[deriving(Clone)] pub struct Comment { pub style: CommentStyle, diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 650f8295d01..2a2bb42cef0 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -34,6 +34,8 @@ pub enum ObsoleteSyntax { ObsoleteExternCrateRenaming, } +impl Copy for ObsoleteSyntax {} + pub trait ParserObsoleteMethods { /// Reports an obsolete syntax non-fatal error. fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index bb3d28ce2bb..4929ee885ac 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -98,6 +98,8 @@ bitflags! { } } +impl Copy for Restrictions {} + type ItemInfo = (Ident, Item_, Option >); /// How to parse a path. There are four different kinds of paths, all of which @@ -114,6 +116,8 @@ pub enum PathParsingMode { LifetimeAndTypesWithColons, } +impl Copy for PathParsingMode {} + enum ItemOrViewItem { /// Indicates a failure to parse any kind of item. The attributes are /// returned. diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 52b54bc7f2d..4b1e9482a7d 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -42,6 +42,8 @@ pub enum BinOpToken { Shr, } +impl Copy for BinOpToken {} + /// A delimeter token #[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash, Show)] pub enum DelimToken { @@ -53,6 +55,8 @@ pub enum DelimToken { Brace, } +impl Copy for DelimToken {} + #[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash, Show)] pub enum IdentStyle { /// `::` follows the identifier with no whitespace in-between. @@ -85,6 +89,12 @@ impl Lit { } } +#[cfg(not(stage0))] +impl Copy for Lit {} + +#[cfg(not(stage0))] +impl Copy for IdentStyle {} + #[allow(non_camel_case_types)] #[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash, Show)] pub enum Token { @@ -435,6 +445,8 @@ macro_rules! declare_special_idents_and_keywords {( $( $rk_variant, )* } + impl Copy for Keyword {} + impl Keyword { pub fn to_name(&self) -> ast::Name { match *self { diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index 7ab3d5dbcd1..c4e040a0f7c 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -72,18 +72,24 @@ pub enum Breaks { Inconsistent, } +impl Copy for Breaks {} + #[deriving(Clone)] pub struct BreakToken { offset: int, blank_space: int } +impl Copy for BreakToken {} + #[deriving(Clone)] pub struct BeginToken { offset: int, breaks: Breaks } +impl Copy for BeginToken {} + #[deriving(Clone)] pub enum Token { String(string::String, int), @@ -152,11 +158,15 @@ pub enum PrintStackBreak { Broken(Breaks), } +impl Copy for PrintStackBreak {} + pub struct PrintStackElem { offset: int, pbreak: PrintStackBreak } +impl Copy for PrintStackElem {} + static SIZE_INFINITY: int = 0xffff; pub fn mk_printer(out: Box, linewidth: uint) -> Printer { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 6ce0ee79c62..eab03f73091 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -47,6 +47,8 @@ pub trait PpAnn { pub struct NoAnn; +impl Copy for NoAnn {} + impl PpAnn for NoAnn {} pub struct CurrentCommentAndLiteral { @@ -54,6 +56,8 @@ pub struct CurrentCommentAndLiteral { cur_lit: uint, } +impl Copy for CurrentCommentAndLiteral {} + pub struct State<'a> { pub s: pp::Printer, cm: Option<&'a CodeMap>, diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 18623ca2a81..f5e89dd61ff 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -44,6 +44,8 @@ pub enum FnKind<'a> { FkFnBlock, } +impl<'a> Copy for FnKind<'a> {} + /// Each method of the Visitor trait is a hook to be potentially /// overridden. Each method's default implementation recursively visits /// the substructure of the input via the corresponding `walk` method; diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index 0e4ecb8f73e..575ec860f97 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -165,6 +165,7 @@ pub mod color { /// Terminal attributes pub mod attr { pub use self::Attr::*; + use std::kinds::Copy; /// Terminal attributes for use with term.attr(). /// @@ -193,6 +194,8 @@ pub mod attr { /// Convenience attribute to set the background color BackgroundColor(super::color::Color) } + + impl Copy for Attr {} } /// A terminal with similar capabilities to an ANSI Terminal diff --git a/src/libterm/terminfo/parm.rs b/src/libterm/terminfo/parm.rs index ee8178fed91..c81bff6a1ae 100644 --- a/src/libterm/terminfo/parm.rs +++ b/src/libterm/terminfo/parm.rs @@ -33,6 +33,8 @@ enum States { SeekIfEndPercent(int) } +impl Copy for States {} + #[deriving(PartialEq)] enum FormatState { FormatStateFlags, @@ -40,6 +42,8 @@ enum FormatState { FormatStatePrecision } +impl Copy for FormatState {} + /// Types of parameters a capability can use #[allow(missing_docs)] #[deriving(Clone)] @@ -452,6 +456,8 @@ struct Flags { space: bool } +impl Copy for Flags {} + impl Flags { fn new() -> Flags { Flags{ width: 0, precision: 0, alternate: false, @@ -467,6 +473,8 @@ enum FormatOp { FormatString } +impl Copy for FormatOp {} + impl FormatOp { fn from_char(c: char) -> FormatOp { match c { diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 06105ca61ca..ffc26738dd7 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -109,7 +109,13 @@ impl Show for TestName { } #[deriving(Clone)] -enum NamePadding { PadNone, PadOnLeft, PadOnRight } +enum NamePadding { + PadNone, + PadOnLeft, + PadOnRight, +} + +impl Copy for NamePadding {} impl TestDesc { fn padded_name(&self, column_count: uint, align: NamePadding) -> String { @@ -179,13 +185,14 @@ impl fmt::Show for TestFn { /// This is feed into functions marked with `#[bench]` to allow for /// set-up & tear-down before running a piece of code repeatedly via a /// call to `iter`. +#[deriving(Copy)] pub struct Bencher { iterations: u64, dur: Duration, pub bytes: u64, } -#[deriving(Clone, Show, PartialEq, Eq, Hash)] +#[deriving(Copy, Clone, Show, PartialEq, Eq, Hash)] pub enum ShouldFail { No, Yes(Option<&'static str>) @@ -212,6 +219,8 @@ pub struct Metric { noise: f64 } +impl Copy for Metric {} + impl Metric { pub fn new(value: f64, noise: f64) -> Metric { Metric {value: value, noise: noise} @@ -238,6 +247,8 @@ pub enum MetricChange { Regression(f64) } +impl Copy for MetricChange {} + pub type MetricDiff = TreeMap; // The default console test runner. It accepts the command line @@ -280,6 +291,8 @@ pub enum ColorConfig { NeverColor, } +impl Copy for ColorConfig {} + pub struct TestOpts { pub filter: Option, pub run_ignored: bool, @@ -1135,7 +1148,7 @@ pub fn run_test(opts: &TestOpts, return; } StaticBenchFn(benchfn) => { - let bs = ::bench::benchmark(|harness| benchfn(harness)); + let bs = ::bench::benchmark(|harness| (benchfn.clone())(harness)); monitor_ch.send((desc, TrBench(bs), Vec::new())); return; } diff --git a/src/libtime/lib.rs b/src/libtime/lib.rs index 4453034fe06..e293c547944 100644 --- a/src/libtime/lib.rs +++ b/src/libtime/lib.rs @@ -77,7 +77,13 @@ mod imp { /// A record specifying a time value in seconds and nanoseconds. #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable, Show)] -pub struct Timespec { pub sec: i64, pub nsec: i32 } +pub struct Timespec { + pub sec: i64, + pub nsec: i32, +} + +impl Copy for Timespec {} + /* * Timespec assumes that pre-epoch Timespecs have negative sec and positive * nsec fields. Darwin's and Linux's struct timespec functions handle pre- @@ -269,6 +275,8 @@ pub struct Tm { pub tm_nsec: i32, } +impl Copy for Tm {} + pub fn empty_tm() -> Tm { Tm { tm_sec: 0_i32, @@ -428,6 +436,8 @@ pub enum ParseError { UnexpectedCharacter(char, char), } +impl Copy for ParseError {} + impl Show for ParseError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { diff --git a/src/libunicode/tables.rs b/src/libunicode/tables.rs index c91ce5c6464..54f7b3501b8 100644 --- a/src/libunicode/tables.rs +++ b/src/libunicode/tables.rs @@ -7138,6 +7138,7 @@ pub mod charwidth { pub mod grapheme { pub use self::GraphemeCat::*; use core::slice::SlicePrelude; + use core::kinds::Copy; use core::slice; #[allow(non_camel_case_types)] @@ -7155,6 +7156,8 @@ pub mod grapheme { GC_Any, } + impl Copy for GraphemeCat {} + fn bsearch_range_value_table(c: char, r: &'static [(char, char, GraphemeCat)]) -> GraphemeCat { use core::cmp::Ordering::{Equal, Less, Greater}; match r.binary_search(|&(lo, hi, _)| { diff --git a/src/test/auxiliary/issue-14422.rs b/src/test/auxiliary/issue-14422.rs index 04e1d993011..9ecb1195de0 100644 --- a/src/test/auxiliary/issue-14422.rs +++ b/src/test/auxiliary/issue-14422.rs @@ -25,6 +25,8 @@ mod src { pub struct A; + impl Copy for A {} + pub fn make() -> B { A } impl A { diff --git a/src/test/auxiliary/issue13213aux.rs b/src/test/auxiliary/issue13213aux.rs index 5bd52ef5010..cf8d0c167a1 100644 --- a/src/test/auxiliary/issue13213aux.rs +++ b/src/test/auxiliary/issue13213aux.rs @@ -22,6 +22,10 @@ mod private { p: i32, } pub const THREE: P = P { p: 3 }; + impl Copy for P {} } pub static A: S = S { p: private::THREE }; + +impl Copy for S {} + diff --git a/src/test/auxiliary/lang-item-public.rs b/src/test/auxiliary/lang-item-public.rs index ea2461ccfa8..e6bae462887 100644 --- a/src/test/auxiliary/lang-item-public.rs +++ b/src/test/auxiliary/lang-item-public.rs @@ -22,3 +22,8 @@ extern fn stack_exhausted() {} #[lang = "eh_personality"] extern fn eh_personality() {} + +#[lang="copy"] +pub trait Copy {} + + diff --git a/src/test/auxiliary/method_self_arg1.rs b/src/test/auxiliary/method_self_arg1.rs index d02222931e5..37022131c3d 100644 --- a/src/test/auxiliary/method_self_arg1.rs +++ b/src/test/auxiliary/method_self_arg1.rs @@ -16,6 +16,8 @@ pub fn get_count() -> u64 { unsafe { COUNT } } pub struct Foo; +impl Copy for Foo {} + impl Foo { pub fn foo(self, x: &Foo) { unsafe { COUNT *= 2; } diff --git a/src/test/auxiliary/method_self_arg2.rs b/src/test/auxiliary/method_self_arg2.rs index 99eb665388b..e1e79b59e3e 100644 --- a/src/test/auxiliary/method_self_arg2.rs +++ b/src/test/auxiliary/method_self_arg2.rs @@ -16,6 +16,8 @@ pub fn get_count() -> u64 { unsafe { COUNT } } pub struct Foo; +impl Copy for Foo {} + impl Foo { pub fn run_trait(self) { unsafe { COUNT *= 17; } diff --git a/src/test/auxiliary/xcrate_unit_struct.rs b/src/test/auxiliary/xcrate_unit_struct.rs index d56d7a70edf..5a918db1cfa 100644 --- a/src/test/auxiliary/xcrate_unit_struct.rs +++ b/src/test/auxiliary/xcrate_unit_struct.rs @@ -14,20 +14,31 @@ pub struct Struct; +impl Copy for Struct {} + pub enum Unit { UnitVariant, Argument(Struct) } +impl Copy for Unit {} + pub struct TupleStruct(pub uint, pub &'static str); +impl Copy for TupleStruct {} + // used by the cfail test pub struct StructWithFields { foo: int, } +impl Copy for StructWithFields {} + pub enum EnumWithVariants { EnumVariant, EnumVariantArg(int) } + +impl Copy for EnumWithVariants {} + diff --git a/src/test/bench/noise.rs b/src/test/bench/noise.rs index 419e39b53cf..025f8467d20 100644 --- a/src/test/bench/noise.rs +++ b/src/test/bench/noise.rs @@ -21,6 +21,8 @@ struct Vec2 { y: f32, } +impl Copy for Vec2 {} + fn lerp(a: f32, b: f32, v: f32) -> f32 { a * (1.0 - v) + b * v } fn smooth(v: f32) -> f32 { v * v * (3.0 - 2.0 * v) } diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs index 3059a014528..e954d0fed5e 100644 --- a/src/test/bench/shootout-chameneos-redux.rs +++ b/src/test/bench/shootout-chameneos-redux.rs @@ -53,7 +53,14 @@ fn print_complements() { } } -enum Color { Red, Yellow, Blue } +enum Color { + Red, + Yellow, + Blue, +} + +impl Copy for Color {} + impl fmt::Show for Color { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let str = match *self { @@ -70,6 +77,8 @@ struct CreatureInfo { color: Color } +impl Copy for CreatureInfo {} + fn show_color_list(set: Vec) -> String { let mut out = String::new(); for col in set.iter() { diff --git a/src/test/bench/shootout-fannkuch-redux.rs b/src/test/bench/shootout-fannkuch-redux.rs index b38b8e66d7d..4b890bbd8d3 100644 --- a/src/test/bench/shootout-fannkuch-redux.rs +++ b/src/test/bench/shootout-fannkuch-redux.rs @@ -67,6 +67,8 @@ struct P { p: [i32, .. 16], } +impl Copy for P {} + struct Perm { cnt: [i32, .. 16], fact: [u32, .. 16], @@ -75,6 +77,8 @@ struct Perm { perm: P, } +impl Copy for Perm {} + impl Perm { fn new(n: u32) -> Perm { let mut fact = [1, .. 16]; diff --git a/src/test/bench/shootout-fasta-redux.rs b/src/test/bench/shootout-fasta-redux.rs index 0b4a1d91968..afffbe5bed4 100644 --- a/src/test/bench/shootout-fasta-redux.rs +++ b/src/test/bench/shootout-fasta-redux.rs @@ -109,6 +109,8 @@ struct AminoAcid { p: f32, } +impl Copy for AminoAcid {} + struct RepeatFasta<'a, W:'a> { alu: &'static str, out: &'a mut W diff --git a/src/test/bench/shootout-k-nucleotide.rs b/src/test/bench/shootout-k-nucleotide.rs index 8ed041513c4..847ae2c1c88 100644 --- a/src/test/bench/shootout-k-nucleotide.rs +++ b/src/test/bench/shootout-k-nucleotide.rs @@ -62,6 +62,8 @@ static OCCURRENCES: [&'static str, ..5] = [ #[deriving(PartialEq, PartialOrd, Ord, Eq)] struct Code(u64); +impl Copy for Code {} + impl Code { fn hash(&self) -> u64 { let Code(ret) = *self; diff --git a/src/test/bench/shootout-nbody.rs b/src/test/bench/shootout-nbody.rs index b62504d7ba8..3f36c16aff6 100644 --- a/src/test/bench/shootout-nbody.rs +++ b/src/test/bench/shootout-nbody.rs @@ -100,6 +100,8 @@ struct Planet { mass: f64, } +impl Copy for Planet {} + fn advance(bodies: &mut [Planet, ..N_BODIES], dt: f64, steps: int) { for _ in range(0, steps) { let mut b_slice = bodies.as_mut_slice(); diff --git a/src/test/compile-fail/borrowck-borrow-from-owned-ptr.rs b/src/test/compile-fail/borrowck-borrow-from-owned-ptr.rs index c071691c947..d5998c8ca99 100644 --- a/src/test/compile-fail/borrowck-borrow-from-owned-ptr.rs +++ b/src/test/compile-fail/borrowck-borrow-from-owned-ptr.rs @@ -14,11 +14,15 @@ struct Foo { bar2: Bar } +impl Copy for Foo {} + struct Bar { int1: int, int2: int, } +impl Copy for Bar {} + fn make_foo() -> Box { panic!() } fn borrow_same_field_twice_mut_mut() { diff --git a/src/test/compile-fail/borrowck-borrow-from-stack-variable.rs b/src/test/compile-fail/borrowck-borrow-from-stack-variable.rs index 3a85b45ad12..d252d442297 100644 --- a/src/test/compile-fail/borrowck-borrow-from-stack-variable.rs +++ b/src/test/compile-fail/borrowck-borrow-from-stack-variable.rs @@ -13,11 +13,15 @@ struct Foo { bar2: Bar } +impl Copy for Foo {} + struct Bar { int1: int, int2: int, } +impl Copy for Bar {} + fn make_foo() -> Foo { panic!() } fn borrow_same_field_twice_mut_mut() { diff --git a/src/test/compile-fail/borrowck-loan-local-as-both-mut-and-imm.rs b/src/test/compile-fail/borrowck-loan-local-as-both-mut-and-imm.rs deleted file mode 100644 index 2063d7388a9..00000000000 --- a/src/test/compile-fail/borrowck-loan-local-as-both-mut-and-imm.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -enum Either { Left(T), Right(U) } - - fn f(x: &mut Either, y: &Either) -> int { - match *y { - Either::Left(ref z) => { - *x = Either::Right(1.0); - *z - } - _ => panic!() - } - } - - fn g() { - let mut x: Either = Either::Left(3); - println!("{}", f(&mut x, &x)); //~ ERROR cannot borrow - } - - fn h() { - let mut x: Either = Either::Left(3); - let y: &Either = &x; - let z: &mut Either = &mut x; //~ ERROR cannot borrow - *z = *y; - } - - fn main() {} diff --git a/src/test/compile-fail/borrowck-use-mut-borrow.rs b/src/test/compile-fail/borrowck-use-mut-borrow.rs index 7414bb930d4..0d27473cb2d 100644 --- a/src/test/compile-fail/borrowck-use-mut-borrow.rs +++ b/src/test/compile-fail/borrowck-use-mut-borrow.rs @@ -9,6 +9,9 @@ // except according to those terms. struct A { a: int, b: int } + +impl Copy for A {} + struct B { a: int, b: Box } fn var_copy_after_var_borrow() { diff --git a/src/test/compile-fail/dst-index.rs b/src/test/compile-fail/dst-index.rs index f6511d68662..af97c864dc8 100644 --- a/src/test/compile-fail/dst-index.rs +++ b/src/test/compile-fail/dst-index.rs @@ -16,6 +16,8 @@ use std::fmt::Show; struct S; +impl Copy for S {} + impl Index for S { fn index<'a>(&'a self, _: &uint) -> &'a str { "hello" @@ -24,6 +26,8 @@ impl Index for S { struct T; +impl Copy for T {} + impl Index for T { fn index<'a>(&'a self, idx: &uint) -> &'a (Show + 'static) { static x: uint = 42; @@ -33,7 +37,8 @@ impl Index for T { fn main() { S[0]; - //~^ ERROR E0161 + //~^ ERROR cannot move out of dereference + //~^^ ERROR E0161 T[0]; //~^ ERROR cannot move out of dereference //~^^ ERROR E0161 diff --git a/src/test/compile-fail/dst-rvalue.rs b/src/test/compile-fail/dst-rvalue.rs index 52b7ea9efa5..4c1dafd8c1a 100644 --- a/src/test/compile-fail/dst-rvalue.rs +++ b/src/test/compile-fail/dst-rvalue.rs @@ -13,8 +13,10 @@ pub fn main() { let _x: Box = box *"hello world"; //~^ ERROR E0161 + //~^^ ERROR cannot move out of dereference let array: &[int] = &[1, 2, 3]; let _x: Box<[int]> = box *array; //~^ ERROR E0161 + //~^^ ERROR cannot move out of dereference } diff --git a/src/test/compile-fail/issue-17651.rs b/src/test/compile-fail/issue-17651.rs index ef8174a26aa..ab396edddf4 100644 --- a/src/test/compile-fail/issue-17651.rs +++ b/src/test/compile-fail/issue-17651.rs @@ -13,5 +13,6 @@ fn main() { (|| box *[0u].as_slice())(); - //~^ ERROR cannot move a value of type [uint] + //~^ ERROR cannot move out of dereference + //~^^ ERROR cannot move a value of type [uint] } diff --git a/src/test/compile-fail/kindck-copy.rs b/src/test/compile-fail/kindck-copy.rs index f0c4a4243ac..8868c7f8256 100644 --- a/src/test/compile-fail/kindck-copy.rs +++ b/src/test/compile-fail/kindck-copy.rs @@ -14,6 +14,7 @@ use std::rc::Rc; fn assert_copy() { } + trait Dummy { } struct MyStruct { @@ -21,6 +22,8 @@ struct MyStruct { y: int, } +impl Copy for MyStruct {} + struct MyNoncopyStruct { x: Box, } diff --git a/src/test/compile-fail/lint-dead-code-1.rs b/src/test/compile-fail/lint-dead-code-1.rs index 1a4a87e608b..9e5f15c2721 100644 --- a/src/test/compile-fail/lint-dead-code-1.rs +++ b/src/test/compile-fail/lint-dead-code-1.rs @@ -12,6 +12,7 @@ #![allow(unused_variables)] #![allow(non_camel_case_types)] #![allow(non_upper_case_globals)] +#![allow(missing_copy_implementations)] #![deny(dead_code)] #![crate_type="lib"] diff --git a/src/test/compile-fail/lint-missing-doc.rs b/src/test/compile-fail/lint-missing-doc.rs index 8d4ecde692d..b73c3fa2610 100644 --- a/src/test/compile-fail/lint-missing-doc.rs +++ b/src/test/compile-fail/lint-missing-doc.rs @@ -13,6 +13,7 @@ #![feature(globs)] #![deny(missing_docs)] #![allow(dead_code)] +#![allow(missing_copy_implementations)] //! Some garbage docs for the crate here #![doc="More garbage"] diff --git a/src/test/compile-fail/opt-in-copy.rs b/src/test/compile-fail/opt-in-copy.rs new file mode 100644 index 00000000000..56f71c844ac --- /dev/null +++ b/src/test/compile-fail/opt-in-copy.rs @@ -0,0 +1,33 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct CantCopyThis; + +struct IWantToCopyThis { + but_i_cant: CantCopyThis, +} + +impl Copy for IWantToCopyThis {} +//~^ ERROR the trait `Copy` may not be implemented for this type + +enum CantCopyThisEither { + A, + B, +} + +enum IWantToCopyThisToo { + ButICant(CantCopyThisEither), +} + +impl Copy for IWantToCopyThisToo {} +//~^ ERROR the trait `Copy` may not be implemented for this type + +fn main() {} + diff --git a/src/test/compile-fail/stage0-clone-contravariant-lifetime.rs b/src/test/compile-fail/stage0-clone-contravariant-lifetime.rs deleted file mode 100644 index 1d1b244ab5a..00000000000 --- a/src/test/compile-fail/stage0-clone-contravariant-lifetime.rs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// A zero-dependency test that covers some basic traits, default -// methods, etc. When mucking about with basic type system stuff I -// often encounter problems in the iterator trait, so it's useful to -// have hanging around. -nmatsakis - -// error-pattern: requires `start` lang_item - -#![no_std] -#![feature(lang_items)] - -#[lang = "sized"] -pub trait Sized for Sized? { - // Empty. -} - -pub mod std { - pub mod clone { - pub trait Clone { - fn clone(&self) -> Self; - } - } -} - -pub struct ContravariantLifetime<'a>; - -impl <'a> ::std::clone::Clone for ContravariantLifetime<'a> { - #[inline] - fn clone(&self) -> ContravariantLifetime<'a> { - match *self { ContravariantLifetime => ContravariantLifetime, } - } -} - -fn main() { } diff --git a/src/test/compile-fail/stage0-cmp.rs b/src/test/compile-fail/stage0-cmp.rs deleted file mode 100644 index f68eb6400fa..00000000000 --- a/src/test/compile-fail/stage0-cmp.rs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - - -// A zero-dependency test that covers some basic traits, default -// methods, etc. When mucking about with basic type system stuff I -// often encounter problems in the iterator trait, so it's useful to -// have hanging around. -nmatsakis - -// error-pattern: requires `start` lang_item - -#![no_std] -#![feature(lang_items)] - -#[lang = "sized"] -pub trait Sized for Sized? { - // Empty. -} - -#[unstable = "Definition may change slightly after trait reform"] -pub trait PartialEq for Sized? { - /// This method tests for `self` and `other` values to be equal, and is used by `==`. - fn eq(&self, other: &Self) -> bool; -} - -#[unstable = "Trait is unstable."] -impl<'a, Sized? T: PartialEq> PartialEq for &'a T { - #[inline] - fn eq(&self, other: & &'a T) -> bool { PartialEq::eq(*self, *other) } -} - -fn main() { } diff --git a/src/test/debuginfo/c-style-enum.rs b/src/test/debuginfo/c-style-enum.rs index fec1d1b2789..b0a0142f6dd 100644 --- a/src/test/debuginfo/c-style-enum.rs +++ b/src/test/debuginfo/c-style-enum.rs @@ -104,18 +104,21 @@ use self::AutoDiscriminant::{One, Two, Three}; use self::ManualDiscriminant::{OneHundred, OneThousand, OneMillion}; use self::SingleVariant::TheOnlyVariant; +#[deriving(Copy)] enum AutoDiscriminant { One, Two, Three } +#[deriving(Copy)] enum ManualDiscriminant { OneHundred = 100, OneThousand = 1000, OneMillion = 1000000 } +#[deriving(Copy)] enum SingleVariant { TheOnlyVariant } diff --git a/src/test/debuginfo/generic-method-on-generic-struct.rs b/src/test/debuginfo/generic-method-on-generic-struct.rs index 7ceac0e7cea..4c0c82efea3 100644 --- a/src/test/debuginfo/generic-method-on-generic-struct.rs +++ b/src/test/debuginfo/generic-method-on-generic-struct.rs @@ -147,3 +147,6 @@ fn main() { } fn zzz() {()} + +impl Copy for Struct {} + diff --git a/src/test/debuginfo/method-on-enum.rs b/src/test/debuginfo/method-on-enum.rs index d86aa54f451..8cb8fae75cf 100644 --- a/src/test/debuginfo/method-on-enum.rs +++ b/src/test/debuginfo/method-on-enum.rs @@ -148,3 +148,6 @@ fn main() { } fn zzz() {()} + +impl Copy for Enum {} + diff --git a/src/test/debuginfo/method-on-generic-struct.rs b/src/test/debuginfo/method-on-generic-struct.rs index 2455c7aa519..d4244ee27d4 100644 --- a/src/test/debuginfo/method-on-generic-struct.rs +++ b/src/test/debuginfo/method-on-generic-struct.rs @@ -147,3 +147,6 @@ fn main() { } fn zzz() {()} + +impl Copy for Struct {} + diff --git a/src/test/debuginfo/method-on-struct.rs b/src/test/debuginfo/method-on-struct.rs index 5e47d32e376..ca00587ba44 100644 --- a/src/test/debuginfo/method-on-struct.rs +++ b/src/test/debuginfo/method-on-struct.rs @@ -146,3 +146,6 @@ fn main() { } fn zzz() {()} + +impl Copy for Struct {} + diff --git a/src/test/debuginfo/method-on-trait.rs b/src/test/debuginfo/method-on-trait.rs index 4d5f53fc120..e70f86a5367 100644 --- a/src/test/debuginfo/method-on-trait.rs +++ b/src/test/debuginfo/method-on-trait.rs @@ -152,3 +152,6 @@ fn main() { } fn zzz() {()} + +impl Copy for Struct {} + diff --git a/src/test/debuginfo/method-on-tuple-struct.rs b/src/test/debuginfo/method-on-tuple-struct.rs index fb3bede37fd..31bdd20e409 100644 --- a/src/test/debuginfo/method-on-tuple-struct.rs +++ b/src/test/debuginfo/method-on-tuple-struct.rs @@ -144,3 +144,6 @@ fn main() { } fn zzz() {()} + +impl Copy for TupleStruct {} + diff --git a/src/test/debuginfo/self-in-default-method.rs b/src/test/debuginfo/self-in-default-method.rs index 287813a959f..87fdb2c42c8 100644 --- a/src/test/debuginfo/self-in-default-method.rs +++ b/src/test/debuginfo/self-in-default-method.rs @@ -148,3 +148,6 @@ fn main() { } fn zzz() {()} + +impl Copy for Struct {} + diff --git a/src/test/debuginfo/self-in-generic-default-method.rs b/src/test/debuginfo/self-in-generic-default-method.rs index bfb8abc9f66..6f488230521 100644 --- a/src/test/debuginfo/self-in-generic-default-method.rs +++ b/src/test/debuginfo/self-in-generic-default-method.rs @@ -149,3 +149,6 @@ fn main() { } fn zzz() {()} + +impl Copy for Struct {} + diff --git a/src/test/pretty/block-disambig.rs b/src/test/pretty/block-disambig.rs index 1b1765475f3..db01bc94e32 100644 --- a/src/test/pretty/block-disambig.rs +++ b/src/test/pretty/block-disambig.rs @@ -21,6 +21,8 @@ fn test2() -> int { let val = &0i; { } *val } struct S { eax: int } +impl Copy for S {} + fn test3() { let regs = &Cell::new(S {eax: 0}); match true { true => { } _ => { } } diff --git a/src/test/run-make/extern-fn-with-packed-struct/test.rs b/src/test/run-make/extern-fn-with-packed-struct/test.rs index 8d8daed1393..12d961bd59e 100644 --- a/src/test/run-make/extern-fn-with-packed-struct/test.rs +++ b/src/test/run-make/extern-fn-with-packed-struct/test.rs @@ -16,6 +16,8 @@ struct Foo { c: i8 } +impl Copy for Foo {} + #[link(name = "test", kind = "static")] extern { fn foo(f: Foo) -> Foo; diff --git a/src/test/run-make/target-specs/foo.rs b/src/test/run-make/target-specs/foo.rs index eeddd5e19a8..cab98204b17 100644 --- a/src/test/run-make/target-specs/foo.rs +++ b/src/test/run-make/target-specs/foo.rs @@ -11,6 +11,9 @@ #![feature(lang_items)] #![no_std] +#[lang="copy"] +trait Copy { } + #[lang="sized"] trait Sized { } diff --git a/src/test/run-pass/borrowck-univariant-enum.rs b/src/test/run-pass/borrowck-univariant-enum.rs index 3d191f6c4b4..df4106c9844 100644 --- a/src/test/run-pass/borrowck-univariant-enum.rs +++ b/src/test/run-pass/borrowck-univariant-enum.rs @@ -15,6 +15,8 @@ enum newtype { newvar(int) } +impl Copy for newtype {} + pub fn main() { // Test that borrowck treats enums with a single variant diff --git a/src/test/run-pass/builtin-superkinds-in-metadata.rs b/src/test/run-pass/builtin-superkinds-in-metadata.rs index 683e7ece871..382caa83c61 100644 --- a/src/test/run-pass/builtin-superkinds-in-metadata.rs +++ b/src/test/run-pass/builtin-superkinds-in-metadata.rs @@ -19,10 +19,12 @@ use trait_superkinds_in_metadata::{RequiresCopy}; struct X(T); -impl RequiresShare for X { } +impl Copy for X {} -impl RequiresRequiresShareAndSend for X { } +impl RequiresShare for X { } -impl RequiresCopy for X { } +impl RequiresRequiresShareAndSend for X { } + +impl RequiresCopy for X { } pub fn main() { } diff --git a/src/test/run-pass/cell-does-not-clone.rs b/src/test/run-pass/cell-does-not-clone.rs index c7c655b3db4..6455f1e4bb2 100644 --- a/src/test/run-pass/cell-does-not-clone.rs +++ b/src/test/run-pass/cell-does-not-clone.rs @@ -24,6 +24,8 @@ impl Clone for Foo { } } +impl Copy for Foo {} + pub fn main() { let x = Cell::new(Foo { x: 22 }); let _y = x.get(); diff --git a/src/test/run-pass/class-impl-very-parameterized-trait.rs b/src/test/run-pass/class-impl-very-parameterized-trait.rs index a0d35fd596b..2a9756d7714 100644 --- a/src/test/run-pass/class-impl-very-parameterized-trait.rs +++ b/src/test/run-pass/class-impl-very-parameterized-trait.rs @@ -14,6 +14,8 @@ use std::cmp; #[deriving(Show)] enum cat_type { tuxedo, tabby, tortoiseshell } +impl Copy for cat_type {} + impl cmp::PartialEq for cat_type { fn eq(&self, other: &cat_type) -> bool { ((*self) as uint) == ((*other) as uint) diff --git a/src/test/run-pass/coherence-impl-in-fn.rs b/src/test/run-pass/coherence-impl-in-fn.rs index 51cd62677ca..df0012e07ec 100644 --- a/src/test/run-pass/coherence-impl-in-fn.rs +++ b/src/test/run-pass/coherence-impl-in-fn.rs @@ -10,6 +10,7 @@ pub fn main() { enum x { foo } + impl Copy for x {} impl ::std::cmp::PartialEq for x { fn eq(&self, other: &x) -> bool { (*self) as int == (*other) as int diff --git a/src/test/run-pass/coherence-where-clause.rs b/src/test/run-pass/coherence-where-clause.rs index faec0c50280..e0d9d569d17 100644 --- a/src/test/run-pass/coherence-where-clause.rs +++ b/src/test/run-pass/coherence-where-clause.rs @@ -28,6 +28,8 @@ struct MyType { dummy: uint } +impl Copy for MyType {} + impl MyTrait for MyType { fn get(&self) -> MyType { (*self).clone() } } diff --git a/src/test/run-pass/const-nullary-univariant-enum.rs b/src/test/run-pass/const-nullary-univariant-enum.rs index fe171a9f73d..9a1a5de9360 100644 --- a/src/test/run-pass/const-nullary-univariant-enum.rs +++ b/src/test/run-pass/const-nullary-univariant-enum.rs @@ -12,6 +12,8 @@ enum Foo { Bar = 0xDEADBEE } +impl Copy for Foo {} + static X: Foo = Foo::Bar; pub fn main() { diff --git a/src/test/run-pass/dst-struct-sole.rs b/src/test/run-pass/dst-struct-sole.rs index 04fe6d5cefd..26cb27cc653 100644 --- a/src/test/run-pass/dst-struct-sole.rs +++ b/src/test/run-pass/dst-struct-sole.rs @@ -33,6 +33,8 @@ fn foo2(x: &Fat<[T]>) { #[deriving(PartialEq,Eq)] struct Bar; +impl Copy for Bar {} + trait ToBar { fn to_bar(&self) -> Bar; } diff --git a/src/test/run-pass/dst-struct.rs b/src/test/run-pass/dst-struct.rs index 6b8e25e8559..bf5b300f7cf 100644 --- a/src/test/run-pass/dst-struct.rs +++ b/src/test/run-pass/dst-struct.rs @@ -49,6 +49,8 @@ fn foo3(x: &Fat>) { #[deriving(PartialEq,Eq)] struct Bar; +impl Copy for Bar {} + trait ToBar { fn to_bar(&self) -> Bar; } diff --git a/src/test/run-pass/dst-trait.rs b/src/test/run-pass/dst-trait.rs index 97627309551..907c7810736 100644 --- a/src/test/run-pass/dst-trait.rs +++ b/src/test/run-pass/dst-trait.rs @@ -17,11 +17,15 @@ struct Fat { #[deriving(PartialEq,Eq)] struct Bar; +impl Copy for Bar {} + #[deriving(PartialEq,Eq)] struct Bar1 { f: int } +impl Copy for Bar1 {} + trait ToBar { fn to_bar(&self) -> Bar; fn to_val(&self) -> int; diff --git a/src/test/run-pass/empty-tag.rs b/src/test/run-pass/empty-tag.rs index 6b780d85459..e5d11ac1adb 100644 --- a/src/test/run-pass/empty-tag.rs +++ b/src/test/run-pass/empty-tag.rs @@ -11,6 +11,8 @@ #[deriving(Show)] enum chan { chan_t, } +impl Copy for chan {} + impl PartialEq for chan { fn eq(&self, other: &chan) -> bool { ((*self) as uint) == ((*other) as uint) diff --git a/src/test/run-pass/enum-discrim-width-stuff.rs b/src/test/run-pass/enum-discrim-width-stuff.rs index deb3f6b6c7c..cf8e742947d 100644 --- a/src/test/run-pass/enum-discrim-width-stuff.rs +++ b/src/test/run-pass/enum-discrim-width-stuff.rs @@ -20,6 +20,7 @@ macro_rules! check { A = 0 } static C: E = E::V; + impl Copy for E {} pub fn check() { assert_eq!(size_of::(), size_of::<$t>()); assert_eq!(E::V as $t, $v as $t); diff --git a/src/test/run-pass/explicit-self-generic.rs b/src/test/run-pass/explicit-self-generic.rs index 829870930a4..eeda299c71f 100644 --- a/src/test/run-pass/explicit-self-generic.rs +++ b/src/test/run-pass/explicit-self-generic.rs @@ -18,10 +18,14 @@ type EqFn = proc(K, K):'static -> bool; struct LM { resize_at: uint, size: uint } +impl Copy for LM {} + enum HashMap { HashMap_(LM) } +impl Copy for HashMap {} + fn linear_map() -> HashMap { HashMap::HashMap_(LM{ resize_at: 32, diff --git a/src/test/run-pass/export-unexported-dep.rs b/src/test/run-pass/export-unexported-dep.rs index 3fc5310a29b..48e9d9dea22 100644 --- a/src/test/run-pass/export-unexported-dep.rs +++ b/src/test/run-pass/export-unexported-dep.rs @@ -15,6 +15,8 @@ mod foo { // not exported enum t { t1, t2, } + impl Copy for t {} + impl PartialEq for t { fn eq(&self, other: &t) -> bool { ((*self) as uint) == ((*other) as uint) diff --git a/src/test/run-pass/expr-copy.rs b/src/test/run-pass/expr-copy.rs index 4a45ce66058..6e9ba4f8f41 100644 --- a/src/test/run-pass/expr-copy.rs +++ b/src/test/run-pass/expr-copy.rs @@ -15,6 +15,8 @@ fn f(arg: &mut A) { struct A { a: int } +impl Copy for A {} + pub fn main() { let mut x = A {a: 10}; f(&mut x); diff --git a/src/test/run-pass/expr-if-struct.rs b/src/test/run-pass/expr-if-struct.rs index 758d726851d..c95ca3fff8c 100644 --- a/src/test/run-pass/expr-if-struct.rs +++ b/src/test/run-pass/expr-if-struct.rs @@ -16,6 +16,8 @@ struct I { i: int } +impl Copy for I {} + fn test_rec() { let rs = if true { I {i: 100} } else { I {i: 101} }; assert_eq!(rs.i, 100); @@ -24,6 +26,8 @@ fn test_rec() { #[deriving(Show)] enum mood { happy, sad, } +impl Copy for mood {} + impl PartialEq for mood { fn eq(&self, other: &mood) -> bool { ((*self) as uint) == ((*other) as uint) diff --git a/src/test/run-pass/expr-match-struct.rs b/src/test/run-pass/expr-match-struct.rs index ea96005dc60..83101a3d2cc 100644 --- a/src/test/run-pass/expr-match-struct.rs +++ b/src/test/run-pass/expr-match-struct.rs @@ -15,6 +15,8 @@ // Tests for match as expressions resulting in struct types struct R { i: int } +impl Copy for R {} + fn test_rec() { let rs = match true { true => R {i: 100}, _ => panic!() }; assert_eq!(rs.i, 100); @@ -23,6 +25,8 @@ fn test_rec() { #[deriving(Show)] enum mood { happy, sad, } +impl Copy for mood {} + impl PartialEq for mood { fn eq(&self, other: &mood) -> bool { ((*self) as uint) == ((*other) as uint) diff --git a/src/test/run-pass/exterior.rs b/src/test/run-pass/exterior.rs index e95c2034131..2ca5f430a2a 100644 --- a/src/test/run-pass/exterior.rs +++ b/src/test/run-pass/exterior.rs @@ -13,6 +13,8 @@ use std::cell::Cell; struct Point {x: int, y: int, z: int} +impl Copy for Point {} + fn f(p: &Cell) { assert!((p.get().z == 12)); p.set(Point {x: 10, y: 11, z: 13}); diff --git a/src/test/run-pass/extern-pass-TwoU16s.rs b/src/test/run-pass/extern-pass-TwoU16s.rs index 6161d31c4a9..2b80a404036 100644 --- a/src/test/run-pass/extern-pass-TwoU16s.rs +++ b/src/test/run-pass/extern-pass-TwoU16s.rs @@ -16,6 +16,8 @@ pub struct TwoU16s { one: u16, two: u16 } +impl Copy for TwoU16s {} + #[link(name = "rust_test_helpers")] extern { pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s; diff --git a/src/test/run-pass/extern-pass-TwoU32s.rs b/src/test/run-pass/extern-pass-TwoU32s.rs index 3e6b6502074..be4998c86fd 100644 --- a/src/test/run-pass/extern-pass-TwoU32s.rs +++ b/src/test/run-pass/extern-pass-TwoU32s.rs @@ -16,6 +16,8 @@ pub struct TwoU32s { one: u32, two: u32 } +impl Copy for TwoU32s {} + #[link(name = "rust_test_helpers")] extern { pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s; diff --git a/src/test/run-pass/extern-pass-TwoU64s.rs b/src/test/run-pass/extern-pass-TwoU64s.rs index 5ad1e89425b..e8d91815bf9 100644 --- a/src/test/run-pass/extern-pass-TwoU64s.rs +++ b/src/test/run-pass/extern-pass-TwoU64s.rs @@ -16,6 +16,8 @@ pub struct TwoU64s { one: u64, two: u64 } +impl Copy for TwoU64s {} + #[link(name = "rust_test_helpers")] extern { pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s; diff --git a/src/test/run-pass/extern-pass-TwoU8s.rs b/src/test/run-pass/extern-pass-TwoU8s.rs index 14ba7c80059..7aa710df800 100644 --- a/src/test/run-pass/extern-pass-TwoU8s.rs +++ b/src/test/run-pass/extern-pass-TwoU8s.rs @@ -16,6 +16,8 @@ pub struct TwoU8s { one: u8, two: u8 } +impl Copy for TwoU8s {} + #[link(name = "rust_test_helpers")] extern { pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s; diff --git a/src/test/run-pass/foreign-fn-with-byval.rs b/src/test/run-pass/foreign-fn-with-byval.rs index 6a26ec44312..5d6815fc3c7 100644 --- a/src/test/run-pass/foreign-fn-with-byval.rs +++ b/src/test/run-pass/foreign-fn-with-byval.rs @@ -14,6 +14,8 @@ pub struct S { z: u64, } +impl Copy for S {} + #[link(name = "rust_test_helpers")] extern { pub fn get_x(x: S) -> u64; diff --git a/src/test/run-pass/generic-fn.rs b/src/test/run-pass/generic-fn.rs index 89f342b4ee5..a341bfe22eb 100644 --- a/src/test/run-pass/generic-fn.rs +++ b/src/test/run-pass/generic-fn.rs @@ -14,6 +14,8 @@ fn id(x: T) -> T { return x; } struct Triple {x: int, y: int, z: int} +impl Copy for Triple {} + pub fn main() { let mut x = 62; let mut y = 63; diff --git a/src/test/run-pass/guards-not-exhaustive.rs b/src/test/run-pass/guards-not-exhaustive.rs index c7f3c9d7182..b1bc40b662d 100644 --- a/src/test/run-pass/guards-not-exhaustive.rs +++ b/src/test/run-pass/guards-not-exhaustive.rs @@ -10,6 +10,8 @@ enum Q { R(Option) } +impl Copy for Q {} + fn xyzzy(q: Q) -> uint { match q { Q::R(S) if S.is_some() => { 0 } diff --git a/src/test/run-pass/guards.rs b/src/test/run-pass/guards.rs index 5bfbe4bf5a0..0157423863c 100644 --- a/src/test/run-pass/guards.rs +++ b/src/test/run-pass/guards.rs @@ -10,6 +10,8 @@ struct Pair { x: int, y: int } +impl Copy for Pair {} + pub fn main() { let a: int = match 10i { x if x < 7 => { 1i } x if x < 11 => { 2i } 10 => { 3i } _ => { 4i } }; diff --git a/src/test/run-pass/issue-12860.rs b/src/test/run-pass/issue-12860.rs index 4496a921e24..1caa04ae0b1 100644 --- a/src/test/run-pass/issue-12860.rs +++ b/src/test/run-pass/issue-12860.rs @@ -20,6 +20,8 @@ struct XYZ { z: int } +impl Copy for XYZ {} + fn main() { let mut connected = HashSet::new(); let mut border = HashSet::new(); diff --git a/src/test/run-pass/issue-19100.rs b/src/test/run-pass/issue-19100.rs index cee5c808f99..0ebd3ae8d97 100644 --- a/src/test/run-pass/issue-19100.rs +++ b/src/test/run-pass/issue-19100.rs @@ -13,6 +13,8 @@ enum Foo { Baz } +impl Copy for Foo {} + impl Foo { fn foo(&self) { match self { diff --git a/src/test/run-pass/issue-2288.rs b/src/test/run-pass/issue-2288.rs index 85dd879c830..1f371f0a1c2 100644 --- a/src/test/run-pass/issue-2288.rs +++ b/src/test/run-pass/issue-2288.rs @@ -12,10 +12,13 @@ trait clam { fn chowder(&self, y: A); } + struct foo { x: A, } +impl Copy for foo {} + impl clam for foo { fn chowder(&self, _y: A) { } diff --git a/src/test/run-pass/issue-2633.rs b/src/test/run-pass/issue-2633.rs index a9ebfbcbf33..bc014f699c7 100644 --- a/src/test/run-pass/issue-2633.rs +++ b/src/test/run-pass/issue-2633.rs @@ -12,6 +12,8 @@ struct cat { meow: extern "Rust" fn(), } +impl Copy for cat {} + fn meow() { println!("meow") } @@ -24,6 +26,8 @@ fn cat() -> cat { struct KittyInfo {kitty: cat} +impl Copy for KittyInfo {} + // Code compiles and runs successfully if we add a + before the first arg fn nyan(kitty: cat, _kitty_info: KittyInfo) { (kitty.meow)(); diff --git a/src/test/run-pass/issue-3121.rs b/src/test/run-pass/issue-3121.rs index d0e995da5f1..9e9d611f1a3 100644 --- a/src/test/run-pass/issue-3121.rs +++ b/src/test/run-pass/issue-3121.rs @@ -13,6 +13,10 @@ enum side { mayo, catsup, vinegar } enum order { hamburger, fries(side), shake } enum meal { to_go(order), for_here(order) } +impl Copy for side {} +impl Copy for order {} +impl Copy for meal {} + fn foo(m: Box, cond: bool) { match *m { meal::to_go(_) => { } diff --git a/src/test/run-pass/issue-3563-3.rs b/src/test/run-pass/issue-3563-3.rs index 4e330b9a0e7..d04d8f92ac4 100644 --- a/src/test/run-pass/issue-3563-3.rs +++ b/src/test/run-pass/issue-3563-3.rs @@ -29,6 +29,8 @@ struct Point { y: int, } +impl Copy for Point {} + // Represents an offset on a canvas. (This has the same structure as a Point. // but different semantics). struct Size { @@ -36,11 +38,15 @@ struct Size { height: int, } +impl Copy for Size {} + struct Rect { top_left: Point, size: Size, } +impl Copy for Rect {} + // Contains the information needed to do shape rendering via ASCII art. struct AsciiArt { width: uint, diff --git a/src/test/run-pass/issue-3743.rs b/src/test/run-pass/issue-3743.rs index bebaad2d297..ada3e37c092 100644 --- a/src/test/run-pass/issue-3743.rs +++ b/src/test/run-pass/issue-3743.rs @@ -13,6 +13,8 @@ struct Vec2 { y: f64 } +impl Copy for Vec2 {} + // methods we want to export as methods as well as operators impl Vec2 { #[inline(always)] diff --git a/src/test/run-pass/issue-3753.rs b/src/test/run-pass/issue-3753.rs index 9fbabed3a94..de6926e5512 100644 --- a/src/test/run-pass/issue-3753.rs +++ b/src/test/run-pass/issue-3753.rs @@ -19,11 +19,15 @@ pub struct Point { y: f64 } +impl Copy for Point {} + pub enum Shape { Circle(Point, f64), Rectangle(Point, Point) } +impl Copy for Shape {} + impl Shape { pub fn area(&self, sh: Shape) -> f64 { match sh { diff --git a/src/test/run-pass/issue-5688.rs b/src/test/run-pass/issue-5688.rs index 73bf375923a..0a13e001fab 100644 --- a/src/test/run-pass/issue-5688.rs +++ b/src/test/run-pass/issue-5688.rs @@ -18,7 +18,11 @@ failed to typecheck correctly. */ struct X { vec: &'static [int] } + +impl Copy for X {} + static V: &'static [X] = &[X { vec: &[1, 2, 3] }]; + pub fn main() { for &v in V.iter() { println!("{}", v.vec); diff --git a/src/test/run-pass/lang-item-public.rs b/src/test/run-pass/lang-item-public.rs index 982d4f6a0b5..81774c73c39 100644 --- a/src/test/run-pass/lang-item-public.rs +++ b/src/test/run-pass/lang-item-public.rs @@ -13,6 +13,7 @@ // ignore-windows #13361 #![no_std] +#![feature(lang_items)] extern crate "lang-item-public" as lang_lib; diff --git a/src/test/run-pass/match-arm-statics.rs b/src/test/run-pass/match-arm-statics.rs index 85fa61266a3..400aab64b4c 100644 --- a/src/test/run-pass/match-arm-statics.rs +++ b/src/test/run-pass/match-arm-statics.rs @@ -38,6 +38,8 @@ const VARIANT2_NORTH: EnumWithStructVariants = EnumWithStructVariants::Variant2 pub mod glfw { pub struct InputState(uint); + impl Copy for InputState {} + pub const RELEASE : InputState = InputState(0); pub const PRESS : InputState = InputState(1); pub const REPEAT : InputState = InputState(2); diff --git a/src/test/run-pass/method-self-arg-trait.rs b/src/test/run-pass/method-self-arg-trait.rs index b821c064cac..36dfe83a9eb 100644 --- a/src/test/run-pass/method-self-arg-trait.rs +++ b/src/test/run-pass/method-self-arg-trait.rs @@ -14,6 +14,8 @@ static mut COUNT: u64 = 1; struct Foo; +impl Copy for Foo {} + trait Bar { fn foo1(&self); fn foo2(self); diff --git a/src/test/run-pass/method-self-arg.rs b/src/test/run-pass/method-self-arg.rs index 3d73f34f8cf..788a25efcf9 100644 --- a/src/test/run-pass/method-self-arg.rs +++ b/src/test/run-pass/method-self-arg.rs @@ -14,6 +14,8 @@ static mut COUNT: uint = 1; struct Foo; +impl Copy for Foo {} + impl Foo { fn foo(self, x: &Foo) { unsafe { COUNT *= 2; } diff --git a/src/test/run-pass/monomorphize-abi-alignment.rs b/src/test/run-pass/monomorphize-abi-alignment.rs index 2233a5c3ea7..f5b51cd4233 100644 --- a/src/test/run-pass/monomorphize-abi-alignment.rs +++ b/src/test/run-pass/monomorphize-abi-alignment.rs @@ -19,12 +19,25 @@ */ struct S { i:u8, t:T } -impl S { fn unwrap(self) -> T { self.t } } + +impl Copy for S {} + +impl S { + fn unwrap(self) -> T { + self.t + } +} + #[deriving(PartialEq, Show)] struct A((u32, u32)); + +impl Copy for A {} + #[deriving(PartialEq, Show)] struct B(u64); +impl Copy for B {} + pub fn main() { static Ca: S = S { i: 0, t: A((13, 104)) }; static Cb: S = S { i: 0, t: B(31337) }; diff --git a/src/test/run-pass/multidispatch1.rs b/src/test/run-pass/multidispatch1.rs index 76c87f5d4c5..87d188418bd 100644 --- a/src/test/run-pass/multidispatch1.rs +++ b/src/test/run-pass/multidispatch1.rs @@ -18,6 +18,8 @@ struct MyType { dummy: uint } +impl Copy for MyType {} + impl MyTrait for MyType { fn get(&self) -> uint { self.dummy } } diff --git a/src/test/run-pass/multidispatch2.rs b/src/test/run-pass/multidispatch2.rs index 13131be93c8..1aa15cc5983 100644 --- a/src/test/run-pass/multidispatch2.rs +++ b/src/test/run-pass/multidispatch2.rs @@ -27,6 +27,8 @@ struct MyType { dummy: uint } +impl Copy for MyType {} + impl MyTrait for MyType { fn get(&self) -> uint { self.dummy } } diff --git a/src/test/run-pass/newtype.rs b/src/test/run-pass/newtype.rs index 0d1103086ae..093fd6c81cc 100644 --- a/src/test/run-pass/newtype.rs +++ b/src/test/run-pass/newtype.rs @@ -10,7 +10,14 @@ struct mytype(Mytype); -struct Mytype {compute: fn(mytype) -> int, val: int} +impl Copy for mytype {} + +struct Mytype { + compute: fn(mytype) -> int, + val: int, +} + +impl Copy for Mytype {} fn compute(i: mytype) -> int { let mytype(m) = i; diff --git a/src/test/run-pass/out-pointer-aliasing.rs b/src/test/run-pass/out-pointer-aliasing.rs index 2a44df7a1b5..5f399deb885 100644 --- a/src/test/run-pass/out-pointer-aliasing.rs +++ b/src/test/run-pass/out-pointer-aliasing.rs @@ -13,6 +13,8 @@ pub struct Foo { _f2: int, } +impl Copy for Foo {} + #[inline(never)] pub fn foo(f: &mut Foo) -> Foo { let ret = *f; diff --git a/src/test/run-pass/overloaded-autoderef-order.rs b/src/test/run-pass/overloaded-autoderef-order.rs index 0a9ac734c26..f0daf371ca7 100644 --- a/src/test/run-pass/overloaded-autoderef-order.rs +++ b/src/test/run-pass/overloaded-autoderef-order.rs @@ -15,6 +15,8 @@ struct DerefWrapper { y: Y } +impl Copy for DerefWrapper {} + impl DerefWrapper { fn get_x(self) -> X { self.x @@ -33,6 +35,8 @@ mod priv_test { pub y: Y } + impl Copy for DerefWrapperHideX {} + impl DerefWrapperHideX { pub fn new(x: X, y: Y) -> DerefWrapperHideX { DerefWrapperHideX { diff --git a/src/test/run-pass/packed-struct-vec.rs b/src/test/run-pass/packed-struct-vec.rs index c20e62351a6..59bb5678b69 100644 --- a/src/test/run-pass/packed-struct-vec.rs +++ b/src/test/run-pass/packed-struct-vec.rs @@ -19,6 +19,8 @@ struct Foo { baz: u64 } +impl Copy for Foo {} + pub fn main() { let foos = [Foo { bar: 1, baz: 2 }, .. 10]; diff --git a/src/test/run-pass/rec-tup.rs b/src/test/run-pass/rec-tup.rs index 0dc547f1a02..8adad012ec6 100644 --- a/src/test/run-pass/rec-tup.rs +++ b/src/test/run-pass/rec-tup.rs @@ -10,6 +10,8 @@ struct Point {x: int, y: int} +impl Copy for Point {} + type rect = (Point, Point); fn fst(r: rect) -> Point { let (fst, _) = r; return fst; } diff --git a/src/test/run-pass/rec.rs b/src/test/run-pass/rec.rs index b9b5cfebb0b..02fcf1ad068 100644 --- a/src/test/run-pass/rec.rs +++ b/src/test/run-pass/rec.rs @@ -13,6 +13,8 @@ struct Rect {x: int, y: int, w: int, h: int} +impl Copy for Rect {} + fn f(r: Rect, x: int, y: int, w: int, h: int) { assert_eq!(r.x, x); assert_eq!(r.y, y); diff --git a/src/test/run-pass/regions-dependent-addr-of.rs b/src/test/run-pass/regions-dependent-addr-of.rs index f074ca9a889..79f8ca48882 100644 --- a/src/test/run-pass/regions-dependent-addr-of.rs +++ b/src/test/run-pass/regions-dependent-addr-of.rs @@ -29,6 +29,8 @@ struct C { f: int } +impl Copy for C {} + fn get_v1(a: &A) -> &int { // Region inferencer must deduce that &v < L2 < L1 let foo = &a.value; // L1 diff --git a/src/test/run-pass/regions-early-bound-used-in-bound-method.rs b/src/test/run-pass/regions-early-bound-used-in-bound-method.rs index c011d11749b..5b4169a4e84 100644 --- a/src/test/run-pass/regions-early-bound-used-in-bound-method.rs +++ b/src/test/run-pass/regions-early-bound-used-in-bound-method.rs @@ -19,6 +19,8 @@ struct Box<'a> { t: &'a int } +impl<'a> Copy for Box<'a> {} + impl<'a> GetRef<'a> for Box<'a> { fn get(&self) -> &'a int { self.t diff --git a/src/test/run-pass/regions-early-bound-used-in-bound.rs b/src/test/run-pass/regions-early-bound-used-in-bound.rs index 58de2e0e20e..73eb7ca7188 100644 --- a/src/test/run-pass/regions-early-bound-used-in-bound.rs +++ b/src/test/run-pass/regions-early-bound-used-in-bound.rs @@ -19,6 +19,8 @@ struct Box<'a, T:'a> { t: &'a T } +impl<'a,T:'a> Copy for Box<'a,T> {} + impl<'a,T:Clone> GetRef<'a,T> for Box<'a,T> { fn get(&self) -> &'a T { self.t diff --git a/src/test/run-pass/regions-early-bound-used-in-type-param.rs b/src/test/run-pass/regions-early-bound-used-in-type-param.rs index 708664f33e9..622f820971f 100644 --- a/src/test/run-pass/regions-early-bound-used-in-type-param.rs +++ b/src/test/run-pass/regions-early-bound-used-in-type-param.rs @@ -19,6 +19,8 @@ struct Box { t: T } +impl Copy for Box {} + impl Get for Box { fn get(&self) -> T { self.t.clone() diff --git a/src/test/run-pass/regions-mock-tcx.rs b/src/test/run-pass/regions-mock-tcx.rs index e13edae330a..e10c12a6037 100644 --- a/src/test/run-pass/regions-mock-tcx.rs +++ b/src/test/run-pass/regions-mock-tcx.rs @@ -32,6 +32,9 @@ enum TypeStructure<'tcx> { TypeInt, TypeFunction(Type<'tcx>, Type<'tcx>), } + +impl<'tcx> Copy for TypeStructure<'tcx> {} + impl<'tcx> PartialEq for TypeStructure<'tcx> { fn eq(&self, other: &TypeStructure<'tcx>) -> bool { match (*self, *other) { @@ -93,6 +96,8 @@ struct NodeId { id: uint } +impl Copy for NodeId {} + type Ast<'ast> = &'ast AstStructure<'ast>; struct AstStructure<'ast> { @@ -100,12 +105,16 @@ struct AstStructure<'ast> { kind: AstKind<'ast> } +impl<'ast> Copy for AstStructure<'ast> {} + enum AstKind<'ast> { ExprInt, ExprVar(uint), ExprLambda(Ast<'ast>), } +impl<'ast> Copy for AstKind<'ast> {} + fn compute_types<'tcx,'ast>(tcx: &mut TypeContext<'tcx,'ast>, ast: Ast<'ast>) -> Type<'tcx> { diff --git a/src/test/run-pass/self-in-mut-slot-immediate-value.rs b/src/test/run-pass/self-in-mut-slot-immediate-value.rs index f2482474073..1603f7f9763 100644 --- a/src/test/run-pass/self-in-mut-slot-immediate-value.rs +++ b/src/test/run-pass/self-in-mut-slot-immediate-value.rs @@ -15,6 +15,8 @@ struct Value { n: int } +impl Copy for Value {} + impl Value { fn squared(mut self) -> Value { self.n *= self.n; diff --git a/src/test/run-pass/shape_intrinsic_tag_then_rec.rs b/src/test/run-pass/shape_intrinsic_tag_then_rec.rs deleted file mode 100644 index 930364c0e22..00000000000 --- a/src/test/run-pass/shape_intrinsic_tag_then_rec.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - - -// Exercises a bug in the shape code that was exposed -// on x86_64: when there is an enum embedded in an -// interior record which is then itself interior to -// something else, shape calculations were off. - -#[deriving(Clone, Show)] -enum opt_span { - //hack (as opposed to option), to make `span` compile - os_none, - os_some(Box), -} - -#[deriving(Clone, Show)] -struct Span { - lo: uint, - hi: uint, - expanded_from: opt_span, -} - -#[deriving(Clone, Show)] -struct Spanned { - data: T, - span: Span, -} - -type ty_ = uint; - -#[deriving(Clone, Show)] -struct Path_ { - global: bool, - idents: Vec , - types: Vec>, -} - -type path = Spanned; -type ty = Spanned; - -#[deriving(Clone, Show)] -struct X { - sp: Span, - path: path, -} - -pub fn main() { - let sp: Span = Span {lo: 57451u, hi: 57542u, expanded_from: opt_span::os_none}; - let t: Box = box Spanned { data: 3u, span: sp.clone() }; - let p_: Path_ = Path_ { - global: true, - idents: vec!("hi".to_string()), - types: vec!(t), - }; - let p: path = Spanned { data: p_, span: sp.clone() }; - let x = X { sp: sp, path: p }; - println!("{}", x.path.clone()); - println!("{}", x.clone()); -} diff --git a/src/test/run-pass/simd-generics.rs b/src/test/run-pass/simd-generics.rs index 68c210b018a..31c29b615fc 100644 --- a/src/test/run-pass/simd-generics.rs +++ b/src/test/run-pass/simd-generics.rs @@ -15,6 +15,8 @@ use std::ops; #[simd] struct f32x4(f32, f32, f32, f32); +impl Copy for f32x4 {} + fn add>(lhs: T, rhs: T) -> T { lhs + rhs } diff --git a/src/test/run-pass/small-enum-range-edge.rs b/src/test/run-pass/small-enum-range-edge.rs index 17d647e58b5..de38a553e12 100644 --- a/src/test/run-pass/small-enum-range-edge.rs +++ b/src/test/run-pass/small-enum-range-edge.rs @@ -14,11 +14,17 @@ #[repr(u8)] enum Eu { Lu = 0, Hu = 255 } + +impl Copy for Eu {} + static CLu: Eu = Eu::Lu; static CHu: Eu = Eu::Hu; #[repr(i8)] enum Es { Ls = -128, Hs = 127 } + +impl Copy for Es {} + static CLs: Es = Es::Ls; static CHs: Es = Es::Hs; diff --git a/src/test/run-pass/struct-return.rs b/src/test/run-pass/struct-return.rs index 63574316fe5..bb06aec23f6 100644 --- a/src/test/run-pass/struct-return.rs +++ b/src/test/run-pass/struct-return.rs @@ -11,8 +11,13 @@ // ignore-lexer-test FIXME #15883 pub struct Quad { a: u64, b: u64, c: u64, d: u64 } + +impl Copy for Quad {} + pub struct Floats { a: f64, b: u8, c: f64 } +impl Copy for Floats {} + mod rustrt { use super::{Floats, Quad}; diff --git a/src/test/run-pass/structured-compare.rs b/src/test/run-pass/structured-compare.rs index 88f72932ca0..d0446d83d2e 100644 --- a/src/test/run-pass/structured-compare.rs +++ b/src/test/run-pass/structured-compare.rs @@ -13,6 +13,8 @@ #[deriving(Show)] enum foo { large, small, } +impl Copy for foo {} + impl PartialEq for foo { fn eq(&self, other: &foo) -> bool { ((*self) as uint) == ((*other) as uint) diff --git a/src/test/run-pass/tag-variant-disr-val.rs b/src/test/run-pass/tag-variant-disr-val.rs index 7aa2ba280ac..cf53c1a912a 100644 --- a/src/test/run-pass/tag-variant-disr-val.rs +++ b/src/test/run-pass/tag-variant-disr-val.rs @@ -20,6 +20,8 @@ enum color { orange = 8 >> 1 } +impl Copy for color {} + impl PartialEq for color { fn eq(&self, other: &color) -> bool { ((*self) as uint) == ((*other) as uint) diff --git a/src/test/run-pass/trait-coercion-generic.rs b/src/test/run-pass/trait-coercion-generic.rs index 1e241ad2278..7d924f977cb 100644 --- a/src/test/run-pass/trait-coercion-generic.rs +++ b/src/test/run-pass/trait-coercion-generic.rs @@ -18,6 +18,8 @@ struct Struct { y: int, } +impl Copy for Struct {} + impl Trait<&'static str> for Struct { fn f(&self, x: &'static str) { println!("Hi, {}!", x); diff --git a/src/test/run-pass/trait-coercion.rs b/src/test/run-pass/trait-coercion.rs index 55beebbf2bc..37d69ddfe07 100644 --- a/src/test/run-pass/trait-coercion.rs +++ b/src/test/run-pass/trait-coercion.rs @@ -19,6 +19,8 @@ struct Struct { y: int, } +impl Copy for Struct {} + impl Trait for Struct { fn f(&self) { println!("Hi!"); diff --git a/src/test/run-pass/typeclasses-eq-example-static.rs b/src/test/run-pass/typeclasses-eq-example-static.rs index a5547c0eea9..6b00a8b5c2d 100644 --- a/src/test/run-pass/typeclasses-eq-example-static.rs +++ b/src/test/run-pass/typeclasses-eq-example-static.rs @@ -18,8 +18,11 @@ trait Equal { fn isEq(a: &Self, b: &Self) -> bool; } +#[deriving(Clone)] enum Color { cyan, magenta, yellow, black } +impl Copy for Color {} + impl Equal for Color { fn isEq(a: &Color, b: &Color) -> bool { match (*a, *b) { @@ -32,6 +35,7 @@ impl Equal for Color { } } +#[deriving(Clone)] enum ColorTree { leaf(Color), branch(Box, Box) @@ -40,9 +44,12 @@ enum ColorTree { impl Equal for ColorTree { fn isEq(a: &ColorTree, b: &ColorTree) -> bool { match (a, b) { - (&leaf(x), &leaf(y)) => { Equal::isEq(&x, &y) } + (&leaf(ref x), &leaf(ref y)) => { + Equal::isEq(&(*x).clone(), &(*y).clone()) + } (&branch(ref l1, ref r1), &branch(ref l2, ref r2)) => { - Equal::isEq(&**l1, &**l2) && Equal::isEq(&**r1, &**r2) + Equal::isEq(&(**l1).clone(), &(**l2).clone()) && + Equal::isEq(&(**r1).clone(), &(**r2).clone()) } _ => { false } } diff --git a/src/test/run-pass/typeclasses-eq-example.rs b/src/test/run-pass/typeclasses-eq-example.rs index 21b9c774e8c..e4b7d2eb60b 100644 --- a/src/test/run-pass/typeclasses-eq-example.rs +++ b/src/test/run-pass/typeclasses-eq-example.rs @@ -17,8 +17,11 @@ trait Equal { fn isEq(&self, a: &Self) -> bool; } +#[deriving(Clone)] enum Color { cyan, magenta, yellow, black } +impl Copy for Color {} + impl Equal for Color { fn isEq(&self, a: &Color) -> bool { match (*self, *a) { @@ -31,6 +34,7 @@ impl Equal for Color { } } +#[deriving(Clone)] enum ColorTree { leaf(Color), branch(Box, Box) @@ -39,9 +43,9 @@ enum ColorTree { impl Equal for ColorTree { fn isEq(&self, a: &ColorTree) -> bool { match (self, a) { - (&leaf(x), &leaf(y)) => { x.isEq(&y) } + (&leaf(ref x), &leaf(ref y)) => { x.isEq(&(*y).clone()) } (&branch(ref l1, ref r1), &branch(ref l2, ref r2)) => { - (&**l1).isEq(&**l2) && (&**r1).isEq(&**r2) + (*l1).isEq(&(**l2).clone()) && (*r1).isEq(&(**r2).clone()) } _ => { false } } diff --git a/src/test/run-pass/ufcs-explicit-self.rs b/src/test/run-pass/ufcs-explicit-self.rs index b96820eee14..b6b9fb67f90 100644 --- a/src/test/run-pass/ufcs-explicit-self.rs +++ b/src/test/run-pass/ufcs-explicit-self.rs @@ -12,6 +12,8 @@ struct Foo { f: int, } +impl Copy for Foo {} + impl Foo { fn foo(self: Foo, x: int) -> int { self.f + x @@ -28,6 +30,8 @@ struct Bar { f: T, } +impl Copy for Bar {} + impl Bar { fn foo(self: Bar, x: int) -> int { x diff --git a/src/test/run-pass/unboxed-closures-monomorphization.rs b/src/test/run-pass/unboxed-closures-monomorphization.rs index 43fb4b296cc..cd97fd96fa3 100644 --- a/src/test/run-pass/unboxed-closures-monomorphization.rs +++ b/src/test/run-pass/unboxed-closures-monomorphization.rs @@ -30,6 +30,9 @@ fn main(){ #[deriving(Show, PartialEq)] struct Foo(uint, &'static str); + + impl Copy for Foo {} + let x = Foo(42, "forty-two"); let f = bar(x); assert_eq!(f.call_once(()), x); From a16f60b1173fae1b971b41780288e2dbe005569d Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 8 Dec 2014 13:21:35 -0500 Subject: [PATCH 2/3] Add a feature opt `opt_out_copy` that allows people to revert to the older behavior temporarily. This feature will eventually transition to REJECTED. --- src/librustc/middle/traits/select.rs | 17 ++++++++-- src/libsyntax/feature_gate.rs | 6 ++++ src/test/run-pass/opt-out-copy.rs | 46 ++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 src/test/run-pass/opt-out-copy.rs diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 5ad0d17ad13..302834f3eac 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -924,7 +924,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Some(ty::BoundCopy) => { debug!("obligation self ty is {}", obligation.self_ty().repr(self.tcx())); - try!(self.assemble_candidates_from_impls(obligation, &mut candidates)); + + // If the user has asked for the older, compatibility + // behavior, ignore user-defined impls here. This will + // go away by the time 1.0 is released. + if !self.tcx().sess.features.borrow().opt_out_copy { + try!(self.assemble_candidates_from_impls(obligation, &mut candidates)); + } + try!(self.assemble_builtin_bound_candidates(ty::BoundCopy, stack, &mut candidates)); @@ -1533,8 +1540,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } ty::BoundCopy => { - // This is an Opt-In Built-In Trait. - return Ok(ParameterBuiltin) + // This is an Opt-In Built-In Trait. So, unless + // the user is asking for the old behavior, we + // don't supply any form of builtin impl. + if !this.tcx().sess.features.borrow().opt_out_copy { + return Ok(ParameterBuiltin) + } } ty::BoundSync => { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index ac36e508f3b..b8f60e77601 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -75,6 +75,9 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[ // to bootstrap fix for #5723. ("issue_5723_bootstrap", Accepted), + // A way to temporary opt out of opt in copy. This will *never* be accepted. + ("opt_out_copy", Active), + // These are used to test this portion of the compiler, they don't actually // mean anything ("test_accepted_feature", Accepted), @@ -101,6 +104,7 @@ pub struct Features { pub import_shadowing: bool, pub visible_private_types: bool, pub quote: bool, + pub opt_out_copy: bool, } impl Copy for Features {} @@ -114,6 +118,7 @@ impl Features { import_shadowing: false, visible_private_types: false, quote: false, + opt_out_copy: false, } } } @@ -441,6 +446,7 @@ pub fn check_crate(span_handler: &SpanHandler, krate: &ast::Crate) -> (Features, import_shadowing: cx.has_feature("import_shadowing"), visible_private_types: cx.has_feature("visible_private_types"), quote: cx.has_feature("quote"), + opt_out_copy: cx.has_feature("opt_out_copy"), }, unknown_features) } diff --git a/src/test/run-pass/opt-out-copy.rs b/src/test/run-pass/opt-out-copy.rs new file mode 100644 index 00000000000..8c7072cfdf5 --- /dev/null +++ b/src/test/run-pass/opt-out-copy.rs @@ -0,0 +1,46 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(opt_out_copy)] + +// Test the opt-out-copy feature guard. This is the same as the +// "opt-in-copy.rs" test from compile-fail, except that it is using +// the feature guard, and hence the structureds in this file are +// implicitly copyable, and hence we get no errors. This test can be +// safely removed once the opt-out-copy "feature" is rejected. + +struct CantCopyThis; + +struct IWantToCopyThis { + but_i_cant: CantCopyThis, +} + +impl Copy for IWantToCopyThis {} + +enum CantCopyThisEither { + A, + B, +} + +enum IWantToCopyThisToo { + ButICant(CantCopyThisEither), +} + +impl Copy for IWantToCopyThisToo {} + +fn is_copy() { } + +fn main() { + is_copy::(); + is_copy::(); + is_copy::(); + is_copy::(); +} + From fcd1f53e4351d241b27c8a3af37e37962811a124 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Mon, 8 Dec 2014 14:07:33 -0800 Subject: [PATCH 3/3] Add some missing Copy implementations --- src/librustrt/unwind.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/librustrt/unwind.rs b/src/librustrt/unwind.rs index 714d30ae4b1..5bc542a84e6 100644 --- a/src/librustrt/unwind.rs +++ b/src/librustrt/unwind.rs @@ -400,14 +400,18 @@ pub mod eabi { #[allow(non_camel_case_types, non_snake_case)] pub mod eabi { pub use self::EXCEPTION_DISPOSITION::*; + use core::prelude::*; use libunwind as uw; use libc::{c_void, c_int}; #[repr(C)] + #[allow(missing_copy_implementations)] pub struct EXCEPTION_RECORD; #[repr(C)] + #[allow(missing_copy_implementations)] pub struct CONTEXT; #[repr(C)] + #[allow(missing_copy_implementations)] pub struct DISPATCHER_CONTEXT; #[repr(C)] @@ -418,6 +422,8 @@ pub mod eabi { ExceptionCollidedUnwind } + impl Copy for EXCEPTION_DISPOSITION {} + type _Unwind_Personality_Fn = extern "C" fn( version: c_int,