]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #19648 : mquandalle/rust/patch-1, r=alexcrichton
authorbors <bors@rust-lang.org>
Wed, 10 Dec 2014 03:41:14 +0000 (03:41 +0000)
committerbors <bors@rust-lang.org>
Wed, 10 Dec 2014 03:41:14 +0000 (03:41 +0000)
328 files changed:
mk/dist.mk
src/compiletest/common.rs
src/doc/guide-crates.md
src/doc/guide-error-handling.md
src/doc/guide-ownership.md
src/doc/guide-pointers.md
src/doc/guide-strings.md
src/doc/guide-unsafe.md
src/doc/guide.md
src/doc/intro.md
src/doc/reference.md
src/etc/make-win-dist.py
src/etc/pkg/rust.iss
src/liballoc/rc.rs
src/libarena/lib.rs
src/libcollections/binary_heap.rs
src/libcollections/btree/map.rs
src/libcollections/dlist.rs
src/libcollections/enum_set.rs
src/libcollections/hash/sip.rs
src/libcollections/ring_buf.rs
src/libcollections/slice.rs
src/libcollections/str.rs
src/libcollections/string.rs
src/libcore/atomic.rs
src/libcore/char.rs
src/libcore/cmp.rs
src/libcore/fmt/mod.rs
src/libcore/fmt/num.rs
src/libcore/fmt/rt.rs
src/libcore/intrinsics.rs
src/libcore/iter.rs
src/libcore/kinds.rs
src/libcore/lib.rs
src/libcore/num/mod.rs
src/libcore/ops.rs
src/libcore/option.rs
src/libcore/ptr.rs
src/libcore/raw.rs
src/libcore/result.rs
src/libcore/simd.rs
src/libcore/slice.rs
src/libcore/str.rs
src/libfmt_macros/lib.rs
src/libgetopts/lib.rs
src/liblibc/lib.rs
src/liblog/lib.rs
src/librand/chacha.rs
src/librand/distributions/exponential.rs
src/librand/distributions/normal.rs
src/librand/isaac.rs
src/librand/lib.rs
src/librand/reseeding.rs
src/librbml/lib.rs
src/libregex/parse.rs
src/libregex/re.rs
src/libregex/vm.rs
src/librustc/lib.rs
src/librustc/lint/builtin.rs
src/librustc/lint/context.rs
src/librustc/lint/mod.rs
src/librustc/metadata/common.rs
src/librustc/metadata/creader.rs
src/librustc/metadata/csearch.rs
src/librustc/metadata/cstore.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/encoder.rs
src/librustc/metadata/filesearch.rs
src/librustc/metadata/loader.rs
src/librustc/metadata/tydecode.rs
src/librustc/middle/borrowck/check_loans.rs
src/librustc/middle/borrowck/gather_loans/mod.rs
src/librustc/middle/borrowck/graphviz.rs
src/librustc/middle/borrowck/mod.rs
src/librustc/middle/borrowck/move_data.rs
src/librustc/middle/cfg/construct.rs
src/librustc/middle/cfg/mod.rs
src/librustc/middle/check_loop.rs
src/librustc/middle/check_match.rs
src/librustc/middle/check_rvalues.rs
src/librustc/middle/check_static.rs
src/librustc/middle/const_eval.rs
src/librustc/middle/dataflow.rs
src/librustc/middle/def.rs
src/librustc/middle/effect.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/fast_reject.rs
src/librustc/middle/graph.rs
src/librustc/middle/infer/mod.rs
src/librustc/middle/infer/region_inference/mod.rs
src/librustc/middle/infer/type_variable.rs
src/librustc/middle/infer/unify.rs
src/librustc/middle/lang_items.rs
src/librustc/middle/liveness.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/recursion_limit.rs [new file with mode: 0644]
src/librustc/middle/region.rs
src/librustc/middle/resolve.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/middle/subst.rs
src/librustc/middle/traits/mod.rs
src/librustc/middle/traits/select.rs
src/librustc/middle/ty.rs
src/librustc/session/config.rs
src/librustc/util/common.rs
src/librustc/util/nodemap.rs
src/librustc_driver/driver.rs
src/librustc_driver/pretty.rs
src/librustc_llvm/diagnostic.rs
src/librustc_llvm/lib.rs
src/librustc_trans/back/write.rs
src/librustc_trans/save/mod.rs
src/librustc_trans/save/recorder.rs
src/librustc_trans/save/span_utils.rs
src/librustc_trans/trans/_match.rs
src/librustc_trans/trans/adt.rs
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/basic_block.rs
src/librustc_trans/trans/cabi.rs
src/librustc_trans/trans/cabi_x86_64.rs
src/librustc_trans/trans/callee.rs
src/librustc_trans/trans/cleanup.rs
src/librustc_trans/trans/closure.rs
src/librustc_trans/trans/common.rs
src/librustc_trans/trans/datum.rs
src/librustc_trans/trans/debuginfo.rs
src/librustc_trans/trans/expr.rs
src/librustc_trans/trans/mod.rs
src/librustc_trans/trans/tvec.rs
src/librustc_trans/trans/type_.rs
src/librustc_trans/trans/type_of.rs
src/librustc_trans/trans/value.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/callee.rs [new file with mode: 0644]
src/librustc_typeck/check/method/confirm.rs
src/librustc_typeck/check/method/mod.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/check/vtable.rs
src/librustc_typeck/check/wf.rs
src/librustc_typeck/check/writeback.rs
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/diagnostics.rs
src/librustc_typeck/rscope.rs
src/librustc_typeck/variance.rs
src/librustdoc/clean/mod.rs
src/librustdoc/doctree.rs
src/librustdoc/html/format.rs
src/librustdoc/html/item_type.rs
src/librustdoc/html/render.rs
src/librustdoc/stability_summary.rs
src/librustrt/bookkeeping.rs
src/librustrt/c_str.rs
src/librustrt/mutex.rs
src/librustrt/unwind.rs
src/librustrt/util.rs
src/libserialize/base64.rs
src/libserialize/hex.rs
src/libserialize/json.rs
src/libserialize/lib.rs
src/libstd/ascii.rs
src/libstd/bitflags.rs
src/libstd/collections/hash/table.rs
src/libstd/comm/mod.rs
src/libstd/dynamic_lib.rs
src/libstd/io/mod.rs
src/libstd/io/net/addrinfo.rs
src/libstd/io/net/ip.rs
src/libstd/io/process.rs
src/libstd/io/util.rs
src/libstd/num/strconv.rs
src/libstd/os.rs
src/libstd/path/windows.rs
src/libstd/rand/mod.rs
src/libstd/sync/poison.rs
src/libstd/sys/common/thread_local.rs
src/libstd/sys/windows/fs.rs
src/libstd/time/duration.rs
src/libsyntax/abi.rs
src/libsyntax/ast.rs
src/libsyntax/ast_map/blocks.rs
src/libsyntax/ast_map/mod.rs
src/libsyntax/ast_util.rs
src/libsyntax/attr.rs
src/libsyntax/codemap.rs
src/libsyntax/diagnostic.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/deriving/cmp/ord.rs
src/libsyntax/ext/deriving/cmp/totalord.rs
src/libsyntax/ext/mtwt.rs
src/libsyntax/feature_gate.rs
src/libsyntax/parse/lexer/comments.rs
src/libsyntax/parse/lexer/mod.rs
src/libsyntax/parse/obsolete.rs
src/libsyntax/parse/parser.rs
src/libsyntax/parse/token.rs
src/libsyntax/print/pp.rs
src/libsyntax/print/pprust.rs
src/libsyntax/visit.rs
src/libterm/lib.rs
src/libterm/terminfo/parm.rs
src/libtest/lib.rs
src/libtime/lib.rs
src/libunicode/tables.rs
src/snapshots.txt
src/test/auxiliary/issue-14422.rs
src/test/auxiliary/issue13213aux.rs
src/test/auxiliary/lang-item-public.rs
src/test/auxiliary/method_self_arg1.rs
src/test/auxiliary/method_self_arg2.rs
src/test/auxiliary/xcrate_unit_struct.rs
src/test/bench/noise.rs
src/test/bench/shootout-chameneos-redux.rs
src/test/bench/shootout-fannkuch-redux.rs
src/test/bench/shootout-fasta-redux.rs
src/test/bench/shootout-k-nucleotide.rs
src/test/bench/shootout-nbody.rs
src/test/compile-fail/borrowck-borrow-from-owned-ptr.rs
src/test/compile-fail/borrowck-borrow-from-stack-variable.rs
src/test/compile-fail/borrowck-loan-local-as-both-mut-and-imm.rs [deleted file]
src/test/compile-fail/borrowck-use-mut-borrow.rs
src/test/compile-fail/dst-index.rs
src/test/compile-fail/dst-rvalue.rs
src/test/compile-fail/explicit-call-to-dtor.rs
src/test/compile-fail/explicit-call-to-supertrait-dtor.rs
src/test/compile-fail/feature-gate-unboxed-closures-manual-impls.rs [new file with mode: 0644]
src/test/compile-fail/feature-gate-unboxed-closures-method-calls.rs [new file with mode: 0644]
src/test/compile-fail/feature-gate-unboxed-closures-ufcs-calls.rs [new file with mode: 0644]
src/test/compile-fail/illegal-ufcs-drop.rs [new file with mode: 0644]
src/test/compile-fail/issue-17651.rs
src/test/compile-fail/kindck-copy.rs
src/test/compile-fail/lifetime-elision-return-type-requires-explicit-lifetime.rs
src/test/compile-fail/lint-dead-code-1.rs
src/test/compile-fail/lint-missing-doc.rs
src/test/compile-fail/opt-in-copy.rs [new file with mode: 0644]
src/test/compile-fail/recursion_limit.rs [new file with mode: 0644]
src/test/compile-fail/stage0-clone-contravariant-lifetime.rs [deleted file]
src/test/compile-fail/stage0-cmp.rs [deleted file]
src/test/compile-fail/unboxed-closure-sugar-equiv.rs
src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs [new file with mode: 0644]
src/test/compile-fail/unboxed-closures-type-mismatch.rs
src/test/compile-fail/unboxed-closures-vtable-mismatch.rs
src/test/debuginfo/c-style-enum.rs
src/test/debuginfo/generic-method-on-generic-struct.rs
src/test/debuginfo/method-on-enum.rs
src/test/debuginfo/method-on-generic-struct.rs
src/test/debuginfo/method-on-struct.rs
src/test/debuginfo/method-on-trait.rs
src/test/debuginfo/method-on-tuple-struct.rs
src/test/debuginfo/self-in-default-method.rs
src/test/debuginfo/self-in-generic-default-method.rs
src/test/debuginfo/var-captured-in-stack-closure.rs
src/test/pretty/block-disambig.rs
src/test/run-make/extern-fn-with-packed-struct/test.rs
src/test/run-make/target-specs/foo.rs
src/test/run-pass-fulldeps/issue-13560.rs
src/test/run-pass/borrowck-univariant-enum.rs
src/test/run-pass/builtin-superkinds-in-metadata.rs
src/test/run-pass/cell-does-not-clone.rs
src/test/run-pass/class-impl-very-parameterized-trait.rs
src/test/run-pass/coherence-impl-in-fn.rs
src/test/run-pass/coherence-where-clause.rs
src/test/run-pass/const-nullary-univariant-enum.rs
src/test/run-pass/dst-struct-sole.rs
src/test/run-pass/dst-struct.rs
src/test/run-pass/dst-trait.rs
src/test/run-pass/empty-tag.rs
src/test/run-pass/enum-discrim-width-stuff.rs
src/test/run-pass/explicit-self-generic.rs
src/test/run-pass/export-unexported-dep.rs
src/test/run-pass/expr-copy.rs
src/test/run-pass/expr-if-struct.rs
src/test/run-pass/expr-match-struct.rs
src/test/run-pass/exterior.rs
src/test/run-pass/extern-pass-TwoU16s.rs
src/test/run-pass/extern-pass-TwoU32s.rs
src/test/run-pass/extern-pass-TwoU64s.rs
src/test/run-pass/extern-pass-TwoU8s.rs
src/test/run-pass/foreign-fn-with-byval.rs
src/test/run-pass/generic-fn.rs
src/test/run-pass/guards-not-exhaustive.rs
src/test/run-pass/guards.rs
src/test/run-pass/issue-12860.rs
src/test/run-pass/issue-18738.rs
src/test/run-pass/issue-19100.rs
src/test/run-pass/issue-2288.rs
src/test/run-pass/issue-2633.rs
src/test/run-pass/issue-3121.rs
src/test/run-pass/issue-3563-3.rs
src/test/run-pass/issue-3743.rs
src/test/run-pass/issue-3753.rs
src/test/run-pass/issue-5688.rs
src/test/run-pass/lang-item-public.rs
src/test/run-pass/match-arm-statics.rs
src/test/run-pass/method-self-arg-trait.rs
src/test/run-pass/method-self-arg.rs
src/test/run-pass/monomorphize-abi-alignment.rs
src/test/run-pass/multidispatch1.rs
src/test/run-pass/multidispatch2.rs
src/test/run-pass/newtype.rs
src/test/run-pass/opt-out-copy.rs [new file with mode: 0644]
src/test/run-pass/out-pointer-aliasing.rs
src/test/run-pass/overloaded-autoderef-order.rs
src/test/run-pass/packed-struct-vec.rs
src/test/run-pass/rec-tup.rs
src/test/run-pass/rec.rs
src/test/run-pass/regions-dependent-addr-of.rs
src/test/run-pass/regions-early-bound-used-in-bound-method.rs
src/test/run-pass/regions-early-bound-used-in-bound.rs
src/test/run-pass/regions-early-bound-used-in-type-param.rs
src/test/run-pass/regions-link-fn-args.rs [new file with mode: 0644]
src/test/run-pass/regions-mock-tcx.rs
src/test/run-pass/self-in-mut-slot-immediate-value.rs
src/test/run-pass/shape_intrinsic_tag_then_rec.rs [deleted file]
src/test/run-pass/simd-generics.rs
src/test/run-pass/small-enum-range-edge.rs
src/test/run-pass/struct-return.rs
src/test/run-pass/structured-compare.rs
src/test/run-pass/tag-variant-disr-val.rs
src/test/run-pass/trait-coercion-generic.rs
src/test/run-pass/trait-coercion.rs
src/test/run-pass/typeclasses-eq-example-static.rs
src/test/run-pass/typeclasses-eq-example.rs
src/test/run-pass/ufcs-explicit-self.rs
src/test/run-pass/ufcs-type-params.rs [new file with mode: 0644]
src/test/run-pass/unboxed-closures-monomorphization.rs
src/test/run-pass/wait-forked-but-failed-child.rs

index 718b5bf6df604f16b08b4e136fccc96362d3eee8..0b9cd86c61fe47c668578026807de3c0fbbf6447 100644 (file)
@@ -123,7 +123,8 @@ PKG_EXE = dist/$(PKG_NAME)-$(CFG_BUILD).exe
 $(PKG_EXE): rust.iss modpath.iss upgrade.iss LICENSE.txt rust-logo.ico \
             $(CSREQ3_T_$(CFG_BUILD)_H_$(CFG_BUILD)) \
             dist-prepare-win
-       $(CFG_PYTHON) $(S)src/etc/make-win-dist.py tmp/dist/win $(CFG_BUILD)
+       $(Q)rm -rf tmp/dist/win/gcc
+       $(CFG_PYTHON) $(S)src/etc/make-win-dist.py tmp/dist/win/rust tmp/dist/win/gcc $(CFG_BUILD)
        @$(call E, ISCC: $@)
        $(Q)$(CFG_ISCC) $<
 
@@ -131,7 +132,7 @@ $(eval $(call DEF_PREPARE,win))
 
 dist-prepare-win: PREPARE_HOST=$(CFG_BUILD)
 dist-prepare-win: PREPARE_TARGETS=$(CFG_BUILD)
-dist-prepare-win: PREPARE_DEST_DIR=tmp/dist/win
+dist-prepare-win: PREPARE_DEST_DIR=tmp/dist/win/rust
 dist-prepare-win: PREPARE_DIR_CMD=$(DEFAULT_PREPARE_DIR_CMD)
 dist-prepare-win: PREPARE_BIN_CMD=$(DEFAULT_PREPARE_BIN_CMD)
 dist-prepare-win: PREPARE_LIB_CMD=$(DEFAULT_PREPARE_LIB_CMD)
index 0a902d970ef3225f4c5a6d9edfa36aaf29ef6e8c..62b757529dc9f46c6781f14fedae18ec45f636e7 100644 (file)
@@ -25,6 +25,8 @@ pub enum Mode {
     Codegen
 }
 
+impl Copy for Mode {}
+
 impl FromStr for Mode {
     fn from_str(s: &str) -> Option<Mode> {
         match s {
index 50d76371cc51e3ce760e83ba17ccf7815e8b6e80..b567c747d6ff94da0faf22e00fa7b2b4527ca96f 100644 (file)
@@ -32,7 +32,7 @@ two languages for those phrases to be in. We'll use this module layout:
               +---------+   |   +-----------+
               |             +---| farewells |
 +---------+   |                 +-----------+
-| phrases |---+ 
+| phrases |---+
 +---------+   |                  +-----------+
               |              +---| greetings |
               +----------+   |   +-----------+
@@ -219,7 +219,7 @@ Put this in `src/english/greetings.rs`:
 
 fn hello() -> String {
     "Hello!".to_string()
-}  
+}
 ```
 
 Put this in `src/english/farewells.rs`:
@@ -229,7 +229,7 @@ Put this in `src/english/farewells.rs`:
 
 fn goodbye() -> String {
     "Goodbye.".to_string()
-} 
+}
 ```
 
 Put this in `src/japanese/greetings.rs`:
@@ -239,7 +239,7 @@ Put this in `src/japanese/greetings.rs`:
 
 fn hello() -> String {
     "こんにちは".to_string()
-}  
+}
 ```
 
 Of course, you can copy and paste this from this web page, or just type
@@ -253,7 +253,7 @@ Put this in `src/japanese/farewells.rs`:
 
 fn goodbye() -> String {
     "さようなら".to_string()
-} 
+}
 ```
 
 (This is "Sayoonara", if you're curious.)
@@ -381,11 +381,11 @@ $ cargo run
 /home/you/projects/phrases/src/japanese/greetings.rs:1:1: 3:2 warning: code is never used: `hello`, #[warn(dead_code)] on by default
 /home/you/projects/phrases/src/japanese/greetings.rs:1 fn hello() -> String {
 /home/you/projects/phrases/src/japanese/greetings.rs:2     "こんにちは".to_string()
-/home/you/projects/phrases/src/japanese/greetings.rs:3 } 
+/home/you/projects/phrases/src/japanese/greetings.rs:3 }
 /home/you/projects/phrases/src/japanese/farewells.rs:1:1: 3:2 warning: code is never used: `goodbye`, #[warn(dead_code)] on by default
 /home/you/projects/phrases/src/japanese/farewells.rs:1 fn goodbye() -> String {
 /home/you/projects/phrases/src/japanese/farewells.rs:2     "さようなら".to_string()
-/home/you/projects/phrases/src/japanese/farewells.rs:3 } 
+/home/you/projects/phrases/src/japanese/farewells.rs:3 }
      Running `target/phrases`
 Hello in English: Hello!
 Goodbye in English: Goodbye.
@@ -452,7 +452,7 @@ fn main() {
 
 Rust will give us a compile-time error:
 
-```{notrust,ignore}
+```{notrust}
    Compiling phrases v0.0.1 (file:///home/you/projects/phrases)
 /home/you/projects/phrases/src/main.rs:4:5: 4:40 error: a value named `hello` has already been imported in this module
 /home/you/projects/phrases/src/main.rs:4 use phrases::japanese::greetings::hello;
index e2a706e59f0f12436f75e185ebd9a7c35c6f2ebe..71ca8913ab34b8443e5eb6de93002a5c82d7b711 100644 (file)
@@ -2,7 +2,7 @@
 
 > The best-laid plans of mice and men
 > Often go awry
-> 
+>
 > "Tae a Moose", Robert Burns
 
 Sometimes, things just go wrong. It's important to have a plan for when the
@@ -76,7 +76,7 @@ fn main() {
 
 This will give us an error:
 
-```{notrust,ignore}
+```{notrust}
 error: non-exhaustive patterns: `_` not covered [E0004]
 ```
 
@@ -189,7 +189,7 @@ panic!("boom");
 
 gives
 
-```{notrust,ignore}
+```{notrust}
 task '<main>' panicked at 'boom', hello.rs:2
 ```
 
index c1180f7e6a93a324bad9659c4ccb70905b7d7245..aebafebf98ed376e893084fac84f8e4f51a5597f 100644 (file)
@@ -93,7 +93,7 @@ must have a deallocation for each allocation. Rust handles this for you. It
 knows that our handle, `x`, is the owning reference to our box. Rust knows that
 `x` will go out of scope at the end of the block, and so it inserts a call to
 deallocate the memory at the end of the scope. Because the compiler does this
-for us, it's impossible to forget. We always exaclty one deallocations paired
+for us, it's impossible to forget. We always have exactly one deallocation paired
 with each of our allocations.
 
 This is pretty straightforward, but what happens when we want to pass our box
@@ -130,7 +130,7 @@ fn add_one(mut num: Box<int>) {
 
 This does not compile, and gives us an error:
 
-```{notrust,ignore}
+```{notrust}
 error: use of moved value: `x`
    println!("{}", x);
                   ^
@@ -186,11 +186,11 @@ This function takes ownership, because it takes a `Box`, which owns its
 contents. But then we give ownership right back.
 
 In the physical world, you can give one of your possessions to someone for a
-short period of time. You still own your posession, you're just letting someone
+short period of time. You still own your possession, you're just letting someone
 else use it for a while. We call that 'lending' something to someone, and that
 person is said to be 'borrowing' that something from you.
 
-Rust's ownershp system also allows an owner to lend out a handle for a limited
+Rust's ownership system also allows an owner to lend out a handle for a limited
 period. This is also called 'borrowing.' Here's a version of `add_one` which
 borrows its argument rather than taking ownership:
 
@@ -231,7 +231,7 @@ fn add_one(num: &int) -> int {
 
 Rust has a feature called 'lifetime elision,' which allows you to not write
 lifetime annotations in certain circumstances. This is one of them. Without
-eliding the liftimes, `add_one` looks like this:
+eliding the lifetimes, `add_one` looks like this:
 
 ```rust
 fn add_one<'a>(num: &'a int) -> int {
@@ -254,7 +254,7 @@ This part _declares_ our lifetimes. This says that `add_one` has one lifetime,
 fn add_two<'a, 'b>(...)
 ```
 
-Then in our parameter list, we use the liftimes we've named:
+Then in our parameter list, we use the lifetimes we've named:
 
 ```{rust,ignore}
 ...(num: &'a int) -> ...
@@ -279,7 +279,7 @@ fn main() {
 }
 ```
 
-As you can see, `struct`s can also have liftimes. In a similar way to functions,
+As you can see, `struct`s can also have lifetimes. In a similar way to functions,
 
 ```{rust}
 struct Foo<'a> {
@@ -295,7 +295,7 @@ x: &'a int,
 # }
 ```
 
-uses it. So why do we need a liftime here? We need to ensure that any reference
+uses it. So why do we need a lifetime here? We need to ensure that any reference
 to a `Foo` cannot outlive the reference to an `int` it contains.
 
 ## Thinking in scopes
@@ -406,7 +406,7 @@ fn main() {
 We try to make four `Wheel`s, each with a `Car` that it's attached to. But the
 compiler knows that on the second iteration of the loop, there's a problem:
 
-```{notrust,ignore}
+```{notrust}
 error: use of moved value: `car`
     Wheel { size: 360, owner: car };
                               ^~~
index f6216760d6477112946c81e79ee7d9589771fe5e..206df711c1a53613e75971439d64f36575fd8d5a 100644 (file)
@@ -84,7 +84,7 @@ println!("{}", x + z);
 
 This gives us an error:
 
-```{notrust,ignore}
+```{notrust}
 hello.rs:6:24: 6:25 error: mismatched types: expected `int` but found `&int` (expected int but found &-ptr)
 hello.rs:6     println!("{}", x + z);
                                   ^
@@ -132,7 +132,7 @@ Pointers are useful in languages that are pass-by-value, rather than
 pass-by-reference. Basically, languages can make two choices (this is made
 up syntax, it's not Rust):
 
-```{notrust,ignore}
+```{ignore}
 func foo(x) {
     x = 5
 }
@@ -152,7 +152,7 @@ and therefore, can change its value. At the comment, `i` will be `5`.
 So what do pointers have to do with this? Well, since pointers point to a
 location in memory...
 
-```{notrust,ignore}
+```{ignore}
 func foo(&int x) {
     *x = 5
 }
@@ -179,7 +179,7 @@ but here are problems with pointers in other languages:
 Uninitialized pointers can cause a problem. For example, what does this program
 do?
 
-```{notrust,ignore}
+```{ignore}
 &int x;
 *x = 5; // whoops!
 ```
@@ -191,7 +191,7 @@ knows. This might be harmless, and it might be catastrophic.
 When you combine pointers and functions, it's easy to accidentally invalidate
 the memory the pointer is pointing to. For example:
 
-```{notrust,ignore}
+```{ignore}
 func make_pointer(): &int {
     x = 5;
 
@@ -213,7 +213,7 @@ As one last example of a big problem with pointers, **aliasing** can be an
 issue. Two pointers are said to alias when they point at the same location
 in memory. Like this:
 
-```{notrust,ignore}
+```{ignore}
 func mutate(&int i, int j) {
     *i = j;
 }
@@ -398,7 +398,7 @@ fn main() {
 
 It gives this error:
 
-```{notrust,ignore}
+```{notrust}
 test.rs:5:8: 5:10 error: cannot assign to `*x` because it is borrowed
 test.rs:5         *x -= 1;
                   ^~
@@ -522,7 +522,7 @@ boxes, though. As a rough approximation, you can treat this Rust code:
 
 As being similar to this C code:
 
-```{notrust,ignore}
+```{ignore}
 {
     int *x;
     x = (int *)malloc(sizeof(int));
@@ -626,7 +626,7 @@ fn main() {
 
 This prints:
 
-```{notrust,ignore}
+```{ignore}
 Cons(1, box Cons(2, box Cons(3, box Nil)))
 ```
 
index 071c9ff013c59d248237af77ed2201436b02cffb..43cc8483bcec54a6784ed71a6c0209b36711f29a 100644 (file)
@@ -181,7 +181,7 @@ for l in s.graphemes(true) {
 
 This prints:
 
-```{notrust,ignore}
+```{text}
 u͔
 n͈̰̎
 i̙̮͚̦
@@ -207,7 +207,7 @@ for l in s.chars() {
 
 This prints:
 
-```{notrust,ignore}
+```{text}
 u
 ͔
 n
@@ -252,7 +252,7 @@ for l in s.bytes() {
 
 This will print:
 
-```{notrust,ignore}
+```{text}
 117
 205
 148
index 5b248126c80f0226bd5b219e094c3b9240ab5efc..bda1b34563208e0317b958b1b1f9e029b7b1d902 100644 (file)
@@ -661,6 +661,9 @@ extern {
     fn abort() -> !;
 }
 
+#[lang = "owned_box"]
+pub struct Box<T>(*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;
index 3f3b533bbd59b86840f515a0f284c5cb20ddedd7..21043cfef1480e6b41b97963f0f5ce44aade292e 100644 (file)
@@ -355,7 +355,7 @@ just `cargo build` and it'll work the right way.
 
 You'll also notice that Cargo has created a new file: `Cargo.lock`.
 
-```{ignore,notrust}
+```{ignore}
 [root]
 name = "hello_world"
 version = "0.0.1"
@@ -426,7 +426,7 @@ x = 10i;
 
 It will give you this error:
 
-```{ignore,notrust}
+```{notrust}
 error: re-assignment of immutable variable `x`
      x = 10i;
      ^~~~~~~
@@ -486,7 +486,7 @@ fn main() {
 You can use `cargo build` on the command line to build it. You'll get a warning,
 but it will still print "Hello, world!":
 
-```{ignore,notrust}
+```{notrust}
    Compiling hello_world v0.0.1 (file:///home/you/projects/hello_world)
 src/main.rs:2:9: 2:10 warning: unused variable: `x`, #[warn(unused_variable)] on by default
 src/main.rs:2     let x: int;
@@ -664,7 +664,7 @@ let y: int = if x == 5i { 10i; } else { 15i; };
 
 Note the semicolons after the 10 and 15. Rust will give us the following error:
 
-```{ignore,notrust}
+```{notrust}
 error: mismatched types: expected `int` but found `()` (expected int but found ())
 ```
 
@@ -747,7 +747,7 @@ fn print_number(x, y) {
 
 You get this error:
 
-```{ignore,notrust}
+```{notrust}
 hello.rs:5:18: 5:19 error: expected `:` but found `,`
 hello.rs:5 fn print_number(x, y) {
 ```
@@ -779,7 +779,7 @@ fn add_one(x: int) -> int {
 
 We would get an error:
 
-```{ignore,notrust}
+```{ignore}
 error: not all control paths return a value
 fn add_one(x: int) -> int {
      x + 1;
@@ -1160,6 +1160,55 @@ Where a `StringResult` is either an `StringOK`, with the result of a computation
 `ErrorReason` with a `String` explaining what caused the computation to fail. These kinds of
 `enum`s are actually very useful and are even part of the standard library.
 
+Enum variants are namespaced under the enum names. For example, here is an example of using
+our `StringResult`:
+
+```rust
+# enum StringResult {
+#     StringOK(String),
+#     ErrorReason(String),
+# }
+fn respond(greeting: &str) -> StringResult {
+    if greeting == "Hello" {
+        StringResult::StringOK("Good morning!".to_string())
+    } else {
+        StringResult::ErrorReason("I didn't understand you!".to_string())
+    }
+}
+```
+
+Notice that we need both the enum name and the variant name: `StringResult::StringOK`, but
+we didn't need to with `Ordering`, we just said `Greater` rather than `Ordering::Greater`.
+There's a reason: the Rust prelude imports the variants of `Ordering` as well as the enum
+itself. We can use the `use` keyword to do something similar with `StringResult`:
+
+```rust
+use StringResult::StringOK;
+use StringResult::ErrorReason;
+
+enum StringResult {
+    StringOK(String),
+    ErrorReason(String),
+}
+
+# fn main() {}
+
+fn respond(greeting: &str) -> StringResult {
+    if greeting == "Hello" {
+        StringOK("Good morning!".to_string())
+    } else {
+        ErrorReason("I didn't understand you!".to_string())
+    }
+}
+```
+
+We'll learn more about `use` later, but it's used to bring names into scope. `use` declarations
+must come before anything else, which looks a little strange in this example, since we `use`
+the variants before we define them. Anyway, in the body of `respond`, we can just say `StringOK`
+now, rather than the full `StringResult::StringOK`. Importing variants can be convenient, but can
+also cause name conflicts, so do this with caution. It's considered good style to rarely import
+variants for this reason.
+
 As you can see `enum`s with values are quite a powerful tool for data representation,
 and can be even more useful when they're generic across types. But before we get to
 generics, let's talk about how to use them with pattern matching, a tool that will
@@ -1197,7 +1246,7 @@ So what's the big advantage here? Well, there are a few. First of all, `match`
 enforces 'exhaustiveness checking.' Do you see that last arm, the one with the
 underscore (`_`)? If we remove that arm, Rust will give us an error:
 
-```{ignore,notrust}
+```{notrust}
 error: non-exhaustive patterns: `_` not covered
 ```
 
@@ -1344,7 +1393,7 @@ for x in range(0i, 10i) {
 
 In slightly more abstract terms,
 
-```{ignore,notrust}
+```{ignore}
 for var in expression {
     code
 }
@@ -1849,7 +1898,7 @@ Before we move on, let me show you one more Cargo command: `run`. `cargo run`
 is kind of like `cargo build`, but it also then runs the produced executable.
 Try it out:
 
-```{notrust,ignore}
+```{notrust}
 $ cargo run
    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
      Running `target/guessing_game`
@@ -1947,7 +1996,7 @@ for this example, it is not important.
 
 Let's try to compile this using `cargo build`:
 
-```{notrust,no_run}
+```{notrust}
 $ cargo build
    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
 src/main.rs:7:26: 7:34 error: the type of this value must be known in this context
@@ -1995,7 +2044,7 @@ fn main() {
 
 Try running our new program a few times:
 
-```{notrust,ignore}
+```{notrust}
 $ cargo run
    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
      Running `target/guessing_game`
@@ -2048,7 +2097,7 @@ fn main() {
 
 And trying it out:
 
-```{notrust,ignore}
+```{notrust}
 $ cargo run
    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
      Running `target/guessing_game`
@@ -2103,7 +2152,7 @@ fn cmp(a: int, b: int) -> Ordering {
 
 If we try to compile, we'll get some errors:
 
-```{notrust,ignore}
+```{notrust}
 $ cargo build
    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
 src/main.rs:20:15: 20:20 error: mismatched types: expected `int` but found `collections::string::String` (expected int but found struct collections::string::String)
@@ -2157,7 +2206,7 @@ fn cmp(a: uint, b: uint) -> Ordering {
 
 And try compiling again:
 
-```{notrust,ignore}
+```{notrust}
 $ cargo build
    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
 src/main.rs:20:15: 20:20 error: mismatched types: expected `uint` but found `collections::string::String` (expected uint but found struct collections::string::String)
@@ -2170,7 +2219,7 @@ This error is similar to the last one: we expected to get a `uint`, but we got
 a `String` instead! That's because our `input` variable is coming from the
 standard input, and you can guess anything. Try it:
 
-```{notrust,ignore}
+```{notrust}
 $ ./target/guessing_game
 Guess the number!
 The secret number is: 73
@@ -2254,7 +2303,7 @@ fn cmp(a: uint, b: uint) -> Ordering {
 
 Let's try it out!
 
-```{notrust,ignore}
+```{notrust}
 $ cargo build
    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
 src/main.rs:22:15: 22:24 error: mismatched types: expected `uint` but found `core::option::Option<uint>` (expected uint but found enum core::option::Option)
@@ -2313,7 +2362,7 @@ fn cmp(a: uint, b: uint) -> Ordering {
 We use a `match` to either give us the `uint` inside of the `Option`, or we
 print an error message and return. Let's give this a shot:
 
-```{notrust,ignore}
+```{notrust}
 $ cargo run
    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
      Running `target/guessing_game`
@@ -2378,7 +2427,7 @@ fn cmp(a: uint, b: uint) -> Ordering {
 
 Let's try it!
 
-```{notrust,ignore}
+```{notrust}
 $ cargo run
    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
      Running `target/guessing_game`
@@ -2455,7 +2504,7 @@ fn cmp(a: uint, b: uint) -> Ordering {
 And try it out. But wait, didn't we just add an infinite loop? Yup. Remember
 that `return`? If we give a non-number answer, we'll `return` and quit. Observe:
 
-```{notrust,ignore}
+```{notrust}
 $ cargo run
    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
      Running `target/guessing_game`
@@ -2587,7 +2636,7 @@ fn cmp(a: uint, b: uint) -> Ordering {
 
 Now we should be good! Let's try:
 
-```{notrust,ignore}
+```{notrust}
 $ cargo run
    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
      Running `target/guessing_game`
@@ -2703,7 +2752,7 @@ $ cd modules
 
 Let's double check our work by compiling:
 
-```{bash,notrust}
+```{bash}
 $ cargo run
    Compiling modules v0.0.1 (file:///home/you/projects/modules)
      Running `target/modules`
@@ -2765,7 +2814,7 @@ mod hello {
 
 It gives an error:
 
-```{notrust,ignore}
+```{notrust}
    Compiling modules v0.0.1 (file:///home/you/projects/modules)
 src/main.rs:2:5: 2:23 error: function `print_hello` is private
 src/main.rs:2     hello::print_hello();
@@ -2789,7 +2838,7 @@ mod hello {
 Usage of the `pub` keyword is sometimes called 'exporting', because
 we're making the function available for other modules. This will work:
 
-```{notrust,ignore}
+```{notrust}
 $ cargo run
    Compiling modules v0.0.1 (file:///home/you/projects/modules)
      Running `target/modules`
@@ -2923,7 +2972,7 @@ $ cd testing
 
 And try it out:
 
-```{notrust,ignore}
+```{notrust}
 $ cargo run
    Compiling testing v0.0.1 (file:///home/you/projects/testing)
      Running `target/testing`
@@ -2955,7 +3004,7 @@ you give them descriptive names. You'll see why in a moment. We then use a
 macro, `assert!`, to assert that something is true. In this case, we're giving
 it `false`, so this test should fail. Let's try it!
 
-```{notrust,ignore}
+```{notrust}
 $ cargo test
    Compiling testing v0.0.1 (file:///home/you/projects/testing)
 /home/you/projects/testing/src/main.rs:1:1: 3:2 warning: function is never used: `main`, #[warn(dead_code)] on by default
@@ -2984,7 +3033,7 @@ task '<main>' failed at 'Some tests failed', /home/you/src/rust/src/libtest/lib.
 
 Lots of output! Let's break this down:
 
-```{notrust,ignore}
+```{ignore}
 $ cargo test
    Compiling testing v0.0.1 (file:///home/you/projects/testing)
 ```
@@ -2992,7 +3041,7 @@ $ cargo test
 You can run all of your tests with `cargo test`. This runs both your tests in
 `tests`, as well as the tests you put inside of your crate.
 
-```{notrust,ignore}
+```{notrust}
 /home/you/projects/testing/src/main.rs:1:1: 3:2 warning: function is never used: `main`, #[warn(dead_code)] on by default
 /home/you/projects/testing/src/main.rs:1 fn main() {
 /home/you/projects/testing/src/main.rs:2     println!("Hello, world!")
@@ -3006,7 +3055,7 @@ case, Rust is warning us that we've written some code that's never used: our
 We'll turn this lint off for just this function soon. For now, just ignore this
 output.
 
-```{notrust,ignore}
+```{ignore}
      Running target/lib-654ce120f310a3a5
 
 running 1 test
@@ -3018,7 +3067,7 @@ with good names? This is why. Here, it says 'test foo' because we called our
 test 'foo.' If we had given it a good name, it'd be more clear which test
 failed, especially as we accumulate more tests.
 
-```{notrust,ignore}
+```{notrust}
 failures:
 
 ---- foo stdout ----
@@ -3049,7 +3098,7 @@ fn foo() {
 
 And then try to run our tests again:
 
-```{notrust,ignore}
+```{ignore}
 $ cargo test
    Compiling testing v0.0.1 (file:///home/you/projects/testing)
      Running target/lib-654ce120f310a3a5
@@ -3089,7 +3138,7 @@ include `main` when it's _not_ true. So we use `not` to negate things:
 With this attribute we won't get the warning (even
 though `src/main.rs` gets recompiled this time):
 
-```{notrust,ignore}
+```{ignore}
 $ cargo test
    Compiling testing v0.0.1 (file:///home/you/projects/testing)
      Running target/lib-654ce120f310a3a5
@@ -3120,7 +3169,7 @@ fn math_checks_out() {
 
 And try to run the test:
 
-```{notrust,ignore}
+```{notrust}
 $ cargo test
    Compiling testing v0.0.1 (file:///home/you/projects/testing)
 /home/you/projects/testing/tests/lib.rs:3:18: 3:38 error: unresolved name `add_three_times_four`.
@@ -3180,7 +3229,7 @@ fn math_checks_out() {
 
 Let's give it a run:
 
-```{ignore,notrust}
+```{ignore}
 $ cargo test
    Compiling testing v0.0.1 (file:///home/you/projects/testing)
      Running target/lib-654ce120f310a3a5
@@ -3229,7 +3278,7 @@ fn times_four(x: int) -> int { x * 4 }
 
 If you run `cargo test`, you should get the same output:
 
-```{ignore,notrust}
+```{ignore}
 $ cargo test
    Compiling testing v0.0.1 (file:///home/you/projects/testing)
      Running target/lib-654ce120f310a3a5
@@ -3283,7 +3332,7 @@ fn test_add_three() {
 
 We'd get this error:
 
-```{notrust,ignore}
+```{notrust}
    Compiling testing v0.0.1 (file:///home/you/projects/testing)
 /home/you/projects/testing/tests/lib.rs:3:5: 3:24 error: function `add_three` is private
 /home/you/projects/testing/tests/lib.rs:3 use testing::add_three;
@@ -3325,7 +3374,7 @@ mod test {
 
 Let's give it a shot:
 
-```{ignore,notrust}
+```{ignore}
 $ cargo test
    Compiling testing v0.0.1 (file:///home/you/projects/testing)
      Running target/lib-654ce120f310a3a5
@@ -3455,7 +3504,7 @@ let y = &mut x;
 
 Rust will complain:
 
-```{ignore,notrust}
+```{notrust}
 error: cannot borrow immutable local variable `x` as mutable
  let y = &mut x;
               ^
@@ -3482,7 +3531,7 @@ let z = &mut x;
 
 It gives us this error:
 
-```{notrust,ignore}
+```{notrust}
 error: cannot borrow `x` as mutable more than once at a time
      let z = &mut x;
                   ^
@@ -3628,7 +3677,7 @@ let z = &mut x;
 
 The error:
 
-```{notrust,ignore}
+```{notrust}
 error: cannot borrow `x` as mutable more than once at a time
      let z = &mut x;
                   ^
@@ -3646,7 +3695,7 @@ note: previous borrow ends here
 
 This error comes in three parts. Let's go over each in turn.
 
-```{notrust,ignore}
+```{notrust}
 error: cannot borrow `x` as mutable more than once at a time
      let z = &mut x;
                   ^
@@ -3655,7 +3704,7 @@ error: cannot borrow `x` as mutable more than once at a time
 This error states the restriction: you cannot lend out something mutable more
 than once at the same time. The borrow checker knows the rules!
 
-```{notrust,ignore}
+```{notrust}
 note: previous borrow of `x` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `x` until the borrow ends
      let y = &mut x;
                   ^
@@ -3667,7 +3716,7 @@ the first mutable borrow occurred. The error showed us the second. So now we
 see both parts of the problem. It also alludes to rule #3, by reminding us that
 we can't change `x` until the borrow is over.
 
-```{notrust,ignore}
+```{ignore}
 note: previous borrow ends here
  fn main() {
      let mut x = 5i;
@@ -3681,8 +3730,8 @@ Here's the second note, which lets us know where the first borrow would be over.
 This is useful, because if we wait to try to borrow `x` after this borrow is
 over, then everything will work.
 
-For more advanced patterns, please consult the [Lifetime
-Guide](guide-lifetimes.html).  You'll also learn what this type signature with
+For more advanced patterns, please consult the [Ownership
+Guide](guide-ownership.html).  You'll also learn what this type signature with
 the `'a` syntax is:
 
 ```{rust,ignore}
@@ -3770,7 +3819,7 @@ let y = &mut x;
 
 This gives us this error:
 
-```{notrust,ignore}
+```{notrust}
 error: cannot use `*x` because it was mutably borrowed
  *x;
  ^~
@@ -4595,7 +4644,7 @@ element reference has the closure it's been given as an argument called on it.
 So this would give us the numbers from `2-100`. Well, almost! If you
 compile the example, you'll get a warning:
 
-```{notrust,ignore}
+```{ignore}
 warning: unused result which must be used: iterator adaptors are lazy and
          do nothing unless consumed, #[warn(unused_must_use)] on by default
  range(1i, 100i).map(|x| x + 1i);
@@ -4625,7 +4674,7 @@ for i in std::iter::count(1i, 5i).take(5) {
 
 This will print
 
-```{notrust,ignore}
+```{ignore}
 1
 6
 11
@@ -4838,7 +4887,7 @@ We can then use `T` inside the rest of the signature: `x` has type `T`, and half
 of the `Result` has type `T`. However, if we try to compile that example, we'll get
 an error:
 
-```{notrust,ignore}
+```{notrust}
 error: binary operation `==` cannot be applied to type `T`
 ```
 
@@ -4894,7 +4943,7 @@ we use `impl Trait for Item`, rather than just `impl Item`.
 So what's the big deal? Remember the error we were getting with our generic
 `inverse` function?
 
-```{notrust,ignore}
+```{notrust}
 error: binary operation `==` cannot be applied to type `T`
 ```
 
@@ -4909,7 +4958,7 @@ fn print_area<T>(shape: T) {
 
 Rust complains:
 
-```{notrust,ignore}
+```{notrust}
 error: type `T` does not implement any method in scope named `area`
 ```
 
@@ -4985,7 +5034,7 @@ fn main() {
 
 This program outputs:
 
-```{notrust,ignore}
+```{ignore}
 This shape has an area of 3.141593
 This shape has an area of 1
 ```
@@ -4999,7 +5048,7 @@ print_area(5i);
 
 We get a compile-time error:
 
-```{notrust,ignore}
+```{ignore}
 error: failed to find an implementation of trait main::HasArea for int
 ```
 
@@ -5066,7 +5115,7 @@ fn main() {
 Now that we've moved the structs and traits into their own module, we get an
 error:
 
-```{notrust,ignore}
+```{notrust}
 error: type `shapes::Circle` does not implement any method in scope named `area`
 ```
 
index 01697a3e0cbc3a5c5925f168ce441d20c2dada2b..e2cccef5b4a1d13afadaf7546874bd4660df5c7d 100644 (file)
@@ -58,13 +58,13 @@ authors = ["Your Name <you@example.com>"]
 ```
 
 This is called a **manifest**, and it contains all of the metadata that Cargo
-needs to compile your project. 
+needs to compile your project.
 
 Here's what's in `src/main.rs`:
 
 ```{rust}
 fn main() {
-    println!("Hello, world!")
+    println!("Hello, world!");
 }
 ```
 
@@ -207,7 +207,7 @@ and two...
 
 ```{bash}
 $ g++ hello.cpp -Wall -Werror
-$ ./a.out 
+$ ./a.out
 Segmentation fault (core dumped)
 ```
 
@@ -313,7 +313,7 @@ print `"Hello"`, or does Rust crash?
 
 Neither. It refuses to compile:
 
-```{notrust,ignore}
+```{notrust}
 $ cargo run
    Compiling hello_world v0.0.1 (file:///Users/you/src/hello_world)
 main.rs:8:5: 8:6 error: cannot borrow `v` as mutable because it is also borrowed as immutable
@@ -428,7 +428,7 @@ fn main() {
 
 It gives us this error:
 
-```{notrust,ignore}
+```{notrust}
 6:71 error: capture of moved value: `numbers`
     for j in range(0, 3) { numbers[j] += 1 }
                ^~~~~~~
index 9ac4469d549838e828b7ddfa16cbcfe58adda26c..660a97cd55f3343465abd15aaf77fc99ef7a6dac 100644 (file)
@@ -496,9 +496,8 @@ Examples of integer literals of various forms:
 
 A _floating-point literal_ has one of two forms:
 
-* Two _decimal literals_ separated by a period
-  character `U+002E` (`.`), with an optional _exponent_ trailing after the
-  second decimal literal.
+* A _decimal literal_ followed by a period character `U+002E` (`.`). This is
+  optionally followed by another decimal literal, with an optional _exponent_.
 * A single _decimal literal_ followed by an _exponent_.
 
 By default, a floating-point literal has a generic type, and, like integer
@@ -509,12 +508,17 @@ types), which explicitly determine the type of the literal.
 Examples of floating-point literals of various forms:
 
 ```
-123.0f64;                          // type f64
-0.1f64;                            // type f64
-0.1f32;                            // type f32
-12E+99_f64;                        // type f64
+123.0f64;        // type f64
+0.1f64;          // type f64
+0.1f32;          // type f32
+12E+99_f64;      // type f64
+let x: f64 = 2.; // type f64
 ```
 
+This last example is different because it is not possible to use the suffix
+syntax with a floating point literal ending in a period. `2.f64` would attempt
+to call a method named `f64` on `2`.
+
 ##### Boolean literals
 
 The two values of the boolean type are written `true` and `false`.
@@ -1660,6 +1664,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 +1674,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 +1798,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;
index 53f648e29ae112110721e3266b65ba2b52da62a7..7fb86f904a20be3e023fb28f4c8a4df383655021 100644 (file)
@@ -8,6 +8,12 @@
 # option. This file may not be copied, modified, or distributed
 # except according to those terms.
 
+# Script parameters:
+#     argv[1] = rust component root,
+#     argv[2] = gcc component root,
+#     argv[3] = target triple
+# The first two correspond to the two installable components defined in the setup script.
+
 import sys, os, shutil, subprocess
 
 def find_files(files, path):
@@ -22,7 +28,7 @@ def find_files(files, path):
             raise Exception("Could not find '%s' in %s" % (fname, path))
     return found
 
-def make_win_dist(dist_root, target_triple):
+def make_win_dist(rust_root, gcc_root, target_triple):
     # Ask gcc where it keeps its stuff
     gcc_out = subprocess.check_output(["gcc.exe", "-print-search-dirs"])
     bin_path = os.environ["PATH"].split(os.pathsep)
@@ -90,29 +96,29 @@ def make_win_dist(dist_root, target_triple):
     target_libs = find_files(target_libs, lib_path)
 
     # Copy runtime dlls next to rustc.exe
-    dist_bin_dir = os.path.join(dist_root, "bin")
+    dist_bin_dir = os.path.join(rust_root, "bin")
     for src in rustc_dlls:
         shutil.copy(src, dist_bin_dir)
 
     # Copy platform tools to platform-specific bin directory
-    target_bin_dir = os.path.join(dist_root, "bin", "rustlib", target_triple, "bin")
+    target_bin_dir = os.path.join(gcc_root, "bin", "rustlib", target_triple, "bin")
     if not os.path.exists(target_bin_dir):
         os.makedirs(target_bin_dir)
     for src in target_tools:
         shutil.copy(src, target_bin_dir)
 
     # Copy platform libs to platform-spcific lib directory
-    target_lib_dir = os.path.join(dist_root, "bin", "rustlib", target_triple, "lib")
+    target_lib_dir = os.path.join(gcc_root, "bin", "rustlib", target_triple, "lib")
     if not os.path.exists(target_lib_dir):
         os.makedirs(target_lib_dir)
     for src in target_libs:
         shutil.copy(src, target_lib_dir)
 
     # Copy license files
-    lic_dir = os.path.join(dist_root, "bin", "third-party")
+    lic_dir = os.path.join(rust_root, "bin", "third-party")
     if os.path.exists(lic_dir):
         shutil.rmtree(lic_dir) # copytree() won't overwrite existing files
     shutil.copytree(os.path.join(os.path.dirname(__file__), "third-party"), lic_dir)
 
 if __name__=="__main__":
-    make_win_dist(sys.argv[1], sys.argv[2])
+    make_win_dist(sys.argv[1], sys.argv[2], sys.argv[3])
index fe2107943c5762e193bade32da249470958bc275..c57a7ab6c7059d98048203d6b9d9dda5ad0e9f78 100644 (file)
@@ -14,6 +14,7 @@ AppPublisherURL=http://www.rust-lang.org
 VersionInfoVersion={#CFG_VERSION_WIN}
 LicenseFile=LICENSE.txt
 
+PrivilegesRequired=lowest
 DisableWelcomePage=true
 DisableProgramGroupPage=true
 DisableReadyPage=true
@@ -37,8 +38,13 @@ Uninstallable=yes
 [Tasks]
 Name: modifypath; Description: &Add {app}\bin to your PATH (recommended)
 
+[Components]
+Name: rust; Description: "Rust compiler and standard crates"; Types: full compact custom; Flags: fixed
+Name: gcc; Description: "Linker and platform libraries"; Types: full
+
 [Files]
-Source: "tmp/dist/win/*.*" ; DestDir: "{app}"; Flags: ignoreversion recursesubdirs
+Source: "tmp/dist/win/rust/*.*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs; Components: rust
+Source: "tmp/dist/win/gcc/*.*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs; Components: gcc
 
 [Code]
 const
index 53891583edb20c768fa2068498511b8a76b2c5b8..217c898e661a0596c2470c149b57201f2df7c72d 100644 (file)
 
 #![stable]
 
+use core::borrow::BorrowFrom;
 use core::cell::Cell;
 use core::clone::Clone;
 use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
@@ -349,6 +350,12 @@ pub fn make_unique(&mut self) -> &mut T {
     }
 }
 
+impl<T> BorrowFrom<Rc<T>> for T {
+    fn borrow_from(owned: &Rc<T>) -> &T {
+        &**owned
+    }
+}
+
 #[experimental = "Deref is experimental."]
 impl<T> Deref<T> for Rc<T> {
     #[inline(always)]
index 8b84ecb690455d53d8eed0cdb9cf3acc06bc9e65..95c4dff323ef0635d713e7be853dda967e345086 100644 (file)
@@ -466,7 +466,7 @@ pub fn alloc(&self, object: T) -> &mut T {
         }
 
         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
index e321ef16f66b5b623424d41a5395ff9cc8e19c87..a4722c340dd7f60dd3a104210ef211f9cb60f6bc 100644 (file)
@@ -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.
index b3dc9139eb32462687778072af23c630794ceeb7..86eaa04b3e2e381835761058b7ace660a5281bf1 100644 (file)
@@ -1026,6 +1026,24 @@ pub fn take(self) -> V {
 
 impl<K, V> BTreeMap<K, V> {
     /// Gets an iterator over the entries of the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeMap;
+    ///
+    /// let mut map = BTreeMap::new();
+    /// map.insert(1u, "a");
+    /// map.insert(2u, "b");
+    /// map.insert(3u, "c");
+    ///
+    /// for (key, value) in map.iter() {
+    ///     println!("{}: {}", key, value);
+    /// }
+    ///
+    /// let (first_key, first_value) = map.iter().next().unwrap();
+    /// assert_eq!((*first_key, *first_value), (1u, "a"));
+    /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn iter<'a>(&'a self) -> Entries<'a, K, V> {
         let len = self.len();
index a30bb9e978b508c6644acd6826bf63c1b8c66058..712c0bcabd58ce15b6181beecd9bd57569d6af43 100644 (file)
@@ -11,9 +11,6 @@
 //! A doubly-linked list with owned nodes.
 //!
 //! The `DList` allows pushing and popping elements at either end.
-//!
-//! `DList` implements the trait `Deque`. It should be imported with
-//! `use collections::Deque`.
 
 // DList is constructed like a singly-linked list over the field `next`.
 // including the last link being None; each Node owns its `next` field.
@@ -39,7 +36,12 @@ pub struct DList<T> {
 }
 
 type Link<T> = Option<Box<Node<T>>>;
-struct Rawlink<T> { p: *mut T }
+
+struct Rawlink<T> {
+    p: *mut T,
+}
+
+impl<T> Copy for Rawlink<T> {}
 
 struct Node<T> {
     next: Link<T>,
@@ -59,6 +61,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<T>,
index 5e77cf66726a872c557409b81b2374c850a55cab..28514b991921180d81fdcab2905dd4a84eda197c 100644 (file)
@@ -27,6 +27,8 @@ pub struct EnumSet<E> {
     bits: uint
 }
 
+impl<E> Copy for EnumSet<E> {}
+
 impl<E:CLike+fmt::Show> fmt::Show for EnumSet<E> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         try!(write!(fmt, "{{"));
@@ -269,6 +271,8 @@ enum Foo {
         A, B, C
     }
 
+    impl Copy for Foo {}
+
     impl CLike for Foo {
         fn to_uint(&self) -> uint {
             *self as uint
@@ -477,6 +481,9 @@ enum Bar {
             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
index ab69a3ad8b883c0dde0a744c16030c3a8e6592fb..9a7aa8c20d3a1c85bc70aa1fff586fc2f2fa4b45 100644 (file)
@@ -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 @@ fn default() -> SipState {
 
 /// `SipHasher` computes the SipHash algorithm from a stream of bytes.
 #[deriving(Clone)]
+#[allow(missing_copy_implementations)]
 pub struct SipHasher {
     k0: u64,
     k1: u64,
index d9e5dde96ceee7693be941db311b068b517dc98b..516b953dad9ba443d21d4e712e30e2e48f4db693 100644 (file)
@@ -11,7 +11,6 @@
 //! This crate implements a double-ended queue with `O(1)` amortized inserts and removals from both
 //! ends of the container. It also has `O(1)` indexing like a vector. The contained elements are
 //! not required to be copyable, and the queue will be sendable if the contained type is sendable.
-//! Its interface `Deque` is defined in `collections`.
 
 use core::prelude::*;
 
@@ -35,7 +34,7 @@
 // FIXME(conventions): implement shrink_to_fit. Awkward with the current design, but it should
 // be scrapped anyway. Defer to rewrite?
 
-/// `RingBuf` is a circular buffer that implements `Deque`.
+/// `RingBuf` is a circular buffer.
 pub struct RingBuf<T> {
     // tail and head are pointers into the buffer. Tail always points
     // to the first element that could be read, Head always points
index 03b8ea8f20fa5de6002dc79c5e54338f24aaff73..c230c48d222bd1b93ded13ab143c5c9dc514948c 100644 (file)
@@ -91,7 +91,7 @@
 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 @@ pub fn new(length: uint) -> 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 @@ impl Clone for S {
             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);
     }
 
index 28027198143f0e847115bf4076bf80f3921ac82b..419d7f270adf197e8eea9f2035a7c4f4f7a54991 100644 (file)
@@ -228,24 +228,32 @@ fn next(&mut self) -> Option<char> {
             _ => 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
+                }
             }
         }
 
index 571f3fa468589967cadf7ad9b0d1543fd1866e84..6943ec69359f8af6d28cfc2eb5104e4133cb5b51 100644 (file)
@@ -729,15 +729,38 @@ fn from_iter<I:Iterator<char>>(iterator: I) -> String {
     }
 }
 
+#[experimental = "waiting on FromIterator stabilization"]
+impl<'a> FromIterator<&'a str> for String {
+    fn from_iter<I:Iterator<&'a str>>(iterator: I) -> String {
+        let mut buf = String::new();
+        buf.extend(iterator);
+        buf
+    }
+}
+
 #[experimental = "waiting on Extend stabilization"]
 impl Extend<char> for String {
     fn extend<I:Iterator<char>>(&mut self, mut iterator: I) {
+        let (lower_bound, _) = iterator.size_hint();
+        self.reserve(lower_bound);
         for ch in iterator {
             self.push(ch)
         }
     }
 }
 
+#[experimental = "waiting on Extend stabilization"]
+impl<'a> Extend<&'a str> for String {
+    fn extend<I: Iterator<&'a str>>(&mut self, mut iterator: I) {
+        // A guess that at least one byte per iterator element will be needed.
+        let (lower_bound, _) = iterator.size_hint();
+        self.reserve(lower_bound);
+        for s in iterator {
+            self.push_str(s)
+        }
+    }
+}
+
 impl PartialEq for String {
     #[inline]
     fn eq(&self, other: &String) -> bool { PartialEq::eq(&**self, &**other) }
@@ -1307,6 +1330,27 @@ fn test_vectors() {
                "[[], [1], [1, 1]]");
     }
 
+    #[test]
+    fn test_from_iterator() {
+        let s = "ศไทย中华Việt Nam".to_string();
+        let t = "ศไทย中华";
+        let u = "Việt Nam";
+
+        let a: String = s.chars().collect();
+        assert_eq!(s, a);
+
+        let mut b = t.to_string();
+        b.extend(u.chars());
+        assert_eq!(s, b);
+
+        let c: String = vec![t, u].into_iter().collect();
+        assert_eq!(s, c);
+
+        let mut d = t.to_string();
+        d.extend(vec![u].into_iter());
+        assert_eq!(s, d);
+    }
+
     #[bench]
     fn bench_with_capacity(b: &mut Bencher) {
         b.iter(|| {
index e930f353b52258b14a3c7b4ca5fa170644275f7c..748f5d774a4bbf9121c9e52a444c3fd6bc102a54 100644 (file)
@@ -17,6 +17,7 @@
 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 =
index 2bebe87a14ce4e1772fdc78a05227f562c6262fa..8485e40819b5b1f1df668d83163b254a21c9f503 100644 (file)
@@ -519,3 +519,4 @@ fn next(&mut self) -> Option<char> {
         }
     }
 }
+
index a5ba2b03b1565b2b8fa0158a9e26ab71e1534bdf..4235531c199a2f09a917ba739a2d279925290687 100644 (file)
@@ -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::{mod, 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.
index 8b2ffd90ef71529dd948d7033633f47a46fa4e67..88ea811cfd694b25eaeae7e920872d424f860f4e 100644 (file)
@@ -46,6 +46,8 @@
 #[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 @@ fn as_uint(&self) -> Option<uint> {
     }
 }
 
+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.
index a441ced03b26ea5e08defdf9cc6611e310f465dc..fa6f48326b56b02e64179c598c2a4cc959601c1b 100644 (file)
@@ -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 @@ fn digit(&self, x: u8) -> u8 {
 #[unstable = "may be renamed or move to a different module"]
 pub struct RadixFmt<T, R>(T, R);
 
+impl<T,R> Copy for RadixFmt<T,R> where T: Copy, R: Copy {}
+
 /// Constructs a radix formatter in the range of `2..36`.
 ///
 /// # Example
index 145e78dc668eeebc1f446a81e6d07d0512582d36..748bd0bc4bd0019ceaf404ccf9a519478716941c 100644 (file)
@@ -20,6 +20,7 @@
 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 {}
index ece2ac6975ed155aa0fe91a0bc76c2bab9804dea..2fc4d23e7fd748968c3d153ef0a54c39a1b91db4 100644 (file)
@@ -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<T: 'static>() -> TypeId {
index 49865bd3c7d5726117db086f6086f14bb6b542ea..ddca9d36bed7ecfc2d1ecb7a5d43d6277fce3254 100644 (file)
@@ -59,6 +59,7 @@
 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<T> {
     iter: T,
 }
 
-#[unstable = "trait is unstable"]
+impl<T:Copy> Copy for Cycle<T> {}
+
 impl<A, T: Clone + Iterator<A>> Iterator<A> for Cycle<T> {
     #[inline]
     fn next(&mut self) -> Option<A> {
@@ -1576,7 +1578,8 @@ pub struct Peekable<A, T> {
     peeked: Option<A>,
 }
 
-#[unstable = "trait is unstable"]
+impl<T:Copy,A:Copy> Copy for Peekable<A,T> {}
+
 impl<A, T: Iterator<A>> Iterator<A> for Peekable<A, T> {
     #[inline]
     fn next(&mut self) -> Option<A> {
@@ -2115,6 +2118,8 @@ pub struct Counter<A> {
     step: A,
 }
 
+impl<A:Copy> Copy for Counter<A> {}
+
 /// Creates a new counter with the specified start/step
 #[inline]
 #[unstable = "may be renamed"]
@@ -2146,6 +2151,8 @@ pub struct Range<A> {
     one: A,
 }
 
+impl<A:Copy> Copy for Range<A> {}
+
 /// Returns an iterator over the given range [start, stop) (that is, starting
 /// at start (inclusive), and ending at stop (exclusive)).
 ///
index 0c2cb9d5910056cd385c6ab84d0de9f2493b96aa..f932acffd3c2ddd9a012922eba0acfb4626edbf8 100644 (file)
@@ -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<T>;
 
+    impl<T> Copy for CovariantType<T> {}
+
     /// 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<T>;
 
+    impl<T> Copy for ContravariantType<T> {}
+
     /// 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<T>;
 
+    impl<T> Copy for InvariantType<T> {}
+
     /// 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;
 }
+
index 5ad9462daf274cfe525ed29cd9c1912ea59db663..84d84cbd5e1905ae2e6b521af96d2abadcadfcdd 100644 (file)
        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)]
+#![feature(default_type_params, unboxed_closures)]
 #![deny(missing_docs)]
 
 mod macros;
index e6946c83cebdfc46af3e2c25b95807c7acfa7598..3c9b68b350b6b7a21d6de8eddd172090b01ee6d0 100644 (file)
@@ -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.
index ce774a66381029d408d06cdd261118181acba4be..9ad4488081576448f4fb6493fa4bed8f3f75d438 100644 (file)
@@ -90,6 +90,8 @@ pub trait Drop {
 /// ```rust
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl Add<Foo, Foo> for Foo {
 ///     fn add(&self, _rhs: &Foo) -> Foo {
 ///       println!("Adding!");
@@ -128,6 +130,8 @@ fn add(&self, other: &$t) -> $t { (*self) + (*other) }
 /// ```rust
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl Sub<Foo, Foo> for Foo {
 ///     fn sub(&self, _rhs: &Foo) -> Foo {
 ///         println!("Subtracting!");
@@ -166,6 +170,8 @@ fn sub(&self, other: &$t) -> $t { (*self) - (*other) }
 /// ```rust
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl Mul<Foo, Foo> for Foo {
 ///     fn mul(&self, _rhs: &Foo) -> Foo {
 ///         println!("Multiplying!");
@@ -204,6 +210,8 @@ fn mul(&self, other: &$t) -> $t { (*self) * (*other) }
 /// ```
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl Div<Foo, Foo> for Foo {
 ///     fn div(&self, _rhs: &Foo) -> Foo {
 ///         println!("Dividing!");
@@ -242,6 +250,8 @@ fn div(&self, other: &$t) -> $t { (*self) / (*other) }
 /// ```
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl Rem<Foo, Foo> for Foo {
 ///     fn rem(&self, _rhs: &Foo) -> Foo {
 ///         println!("Remainder-ing!");
@@ -294,6 +304,8 @@ fn rem(&self, other: &$t) -> $t {
 /// ```
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl Neg<Foo> for Foo {
 ///     fn neg(&self) -> Foo {
 ///         println!("Negating!");
@@ -348,6 +360,8 @@ fn neg(&self) -> $t { -(*self as $t_signed) as $t }
 /// ```
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl Not<Foo> for Foo {
 ///     fn not(&self) -> Foo {
 ///         println!("Not-ing!");
@@ -387,6 +401,8 @@ fn not(&self) -> $t { !*self }
 /// ```
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl BitAnd<Foo, Foo> for Foo {
 ///     fn bitand(&self, _rhs: &Foo) -> Foo {
 ///         println!("Bitwise And-ing!");
@@ -425,6 +441,8 @@ fn bitand(&self, rhs: &$t) -> $t { (*self) & (*rhs) }
 /// ```
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl BitOr<Foo, Foo> for Foo {
 ///     fn bitor(&self, _rhs: &Foo) -> Foo {
 ///         println!("Bitwise Or-ing!");
@@ -463,6 +481,8 @@ fn bitor(&self, rhs: &$t) -> $t { (*self) | (*rhs) }
 /// ```
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl BitXor<Foo, Foo> for Foo {
 ///     fn bitxor(&self, _rhs: &Foo) -> Foo {
 ///         println!("Bitwise Xor-ing!");
@@ -501,6 +521,8 @@ fn bitxor(&self, other: &$t) -> $t { (*self) ^ (*other) }
 /// ```
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl Shl<Foo, Foo> for Foo {
 ///     fn shl(&self, _rhs: &Foo) -> Foo {
 ///         println!("Shifting left!");
@@ -541,6 +563,8 @@ fn shl(&self, other: &uint) -> $t {
 /// ```
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl Shr<Foo, Foo> for Foo {
 ///     fn shr(&self, _rhs: &Foo) -> Foo {
 ///         println!("Shifting right!");
@@ -580,6 +604,8 @@ fn shr(&self, other: &uint) -> $t { (*self) >> (*other) }
 /// ```
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl Index<Foo, Foo> for Foo {
 ///     fn index<'a>(&'a self, _index: &Foo) -> &'a Foo {
 ///         println!("Indexing!");
@@ -608,6 +634,8 @@ pub trait Index<Sized? Index, Sized? Result> for Sized? {
 /// ```
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl IndexMut<Foo, Foo> for Foo {
 ///     fn index_mut<'a>(&'a mut self, _index: &Foo) -> &'a mut Foo {
 ///         println!("Indexing!");
@@ -636,6 +664,8 @@ pub trait IndexMut<Sized? Index, Sized? Result> for Sized? {
 /// ```ignore
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl Slice<Foo, Foo> for Foo {
 ///     fn as_slice_<'a>(&'a self) -> &'a Foo {
 ///         println!("Slicing!");
@@ -682,6 +712,8 @@ pub trait Slice<Sized? Idx, Sized? Result> for Sized? {
 /// ```ignore
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl SliceMut<Foo, Foo> for Foo {
 ///     fn as_mut_slice_<'a>(&'a mut self) -> &'a mut Foo {
 ///         println!("Slicing!");
@@ -812,12 +844,12 @@ pub trait FnMut<Args,Result> for Sized? {
 
 /// A version of the call operator that takes a by-value receiver.
 #[lang="fn_once"]
-pub trait FnOnce<Args,Result> for Sized? {
+pub trait FnOnce<Args,Result> {
     /// This is called when the call operator is used.
     extern "rust-call" fn call_once(self, args: Args) -> Result;
 }
 
-impl<F,A,R> FnMut<A,R> for F
+impl<Sized? F,A,R> FnMut<A,R> for F
     where F : Fn<A,R>
 {
     extern "rust-call" fn call_mut(&mut self, args: A) -> R {
@@ -832,3 +864,53 @@ extern "rust-call" fn call_once(mut self, args: A) -> R {
         self.call_mut(args)
     }
 }
+
+#[cfg(stage0)]
+mod fn_impls {
+    use super::Fn;
+
+    impl<Result> Fn<(),Result> for extern "Rust" fn() -> Result {
+        #[allow(non_snake_case)]
+        extern "rust-call" fn call(&self, _args: ()) -> Result {
+            (*self)()
+        }
+    }
+
+    impl<Result,A0> Fn<(A0,),Result> for extern "Rust" fn(A0) -> Result {
+        #[allow(non_snake_case)]
+        extern "rust-call" fn call(&self, args: (A0,)) -> Result {
+            let (a0,) = args;
+            (*self)(a0)
+        }
+    }
+
+    macro_rules! def_fn(
+        ($($args:ident)*) => (
+            impl<Result$(,$args)*>
+            Fn<($($args,)*),Result>
+            for extern "Rust" fn($($args: $args,)*) -> Result {
+                #[allow(non_snake_case)]
+                extern "rust-call" fn call(&self, args: ($($args,)*)) -> Result {
+                    let ($($args,)*) = args;
+                    (*self)($($args,)*)
+                }
+            }
+        )
+    )
+
+    def_fn!(A0 A1)
+    def_fn!(A0 A1 A2)
+    def_fn!(A0 A1 A2 A3)
+    def_fn!(A0 A1 A2 A3 A4)
+    def_fn!(A0 A1 A2 A3 A4 A5)
+    def_fn!(A0 A1 A2 A3 A4 A5 A6)
+    def_fn!(A0 A1 A2 A3 A4 A5 A6 A7)
+    def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8)
+    def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9)
+    def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10)
+    def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11)
+    def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12)
+    def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13)
+    def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14)
+    def_fn!(A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15)
+}
index 8ba41c3575fff5cb2afa11b87b71d63899cc128c..0697dfbb0f2e4bae53f8460de8fb84ca40a40c38 100644 (file)
 
 #![stable]
 
+#[cfg(stage0)]
 pub use self::Option::*;
+#[cfg(not(stage0))]
+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 +862,6 @@ fn next(&mut self) -> Option<T> {
         }
     }
 }
+
+impl<T:Copy> Copy for Option<T> {}
+
index 3f6ac49786d2e393e41c583fabc0357ce5701648..5c61a1ed103687ba65c8804b85465ab000c197d3 100644 (file)
@@ -437,3 +437,4 @@ fn gt(&self, other: &*mut T) -> bool { *self > *other }
     #[inline]
     fn ge(&self, other: &*mut T) -> bool { *self >= *other }
 }
+
index d156f71462dd1dda740e1d3791a546e132528f17..db1be94b2b83feb53c684e4c367d9347a359af37 100644 (file)
@@ -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<T> {
     pub len: uint,
 }
 
+impl<T> Copy for Slice<T> {}
+
 /// 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<T> for Sized? {
index 0cf8e6affd71e0a18121e5f03b4013299a51f153..8125afee13f586ab31e946cf1f5341d959f8b020 100644 (file)
 
 #![stable]
 
-pub use self::Result::*;
+use self::Result::*;
 
+use kinds::Copy;
 use std::fmt::Show;
 use slice;
 use slice::AsSlice;
@@ -916,3 +917,7 @@ pub fn fold<T,
     }
     Ok(init)
 }
+
+#[cfg(not(stage0))]
+impl<T:Copy,U:Copy> Copy for Result<T,U> {}
+
index 2b6f97cf6a5c4102468fd6b83688ac3d1253d149..369a7106583070e701c3d695f073a7bcefc58bfa 100644 (file)
@@ -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 {}
+
index b8df36c91bc3e699852c9065849ec582ad86fa7c..4e3007b55fe04cf0406eecd0f2bf45741ccc15e3 100644 (file)
@@ -41,6 +41,7 @@
 use cmp;
 use default::Default;
 use iter::*;
+use kinds::Copy;
 use num::Int;
 use ops;
 use option::Option;
@@ -1157,6 +1158,8 @@ pub fn as_slice(&self) -> &'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 @@ macro_rules! impl_int_slice {
 impl_int_slice!(u32,  i32)
 impl_int_slice!(u64,  i64)
 impl_int_slice!(uint, int)
+
index 1d59567cbe4474d7dc4c862fa58310262129aaf1..baa739b06833ce82f9247c75edb0b14dc0cb8f21 100644 (file)
@@ -26,7 +26,7 @@
 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;
@@ -76,7 +76,7 @@ fn from_str(s: &str) -> Option<bool> {
 Section: Creating a string
 */
 
-/// Converts a vector to a string slice without performing any allocations.
+/// Converts a slice of bytes to a string slice without performing any allocations.
 ///
 /// Once the slice has been validated as utf-8, it is transmuted in-place and
 /// returned as a '&str' instead of a '&[u8]'
@@ -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 @@ fn len(&self) -> uint { self.repr().len }
 impl<'a> Default for &'a str {
     fn default() -> &'a str { "" }
 }
+
index d88551eb85561ec971841609e2d614998a4a0ba5..db389457a1e4759821cde69ed9cfa39487c7f6d7 100644 (file)
@@ -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.
index ffcc0eb22f6138fc434ddec2b18e8eb52ee4ba8a..9174f8e8456f33908d4ccc2d906f7045b480af9a 100644 (file)
@@ -97,6 +97,9 @@
 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<Matches, Fail>;
 
@@ -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;
index 18e9d832c003d04836aa7b610a9f2f3357893b4f..8825099e36c35b071d3b16a3deef0c19b78815db 100644 (file)
@@ -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 c95 {
             /// 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 c99 {
             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 posix01 {
                 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 struct glob_t {
                 }
 
                 #[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 bsd44 {
                 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 struct sockaddr_in6 {
                     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 struct addrinfo {
                     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 posix01 {
                 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 struct stat {
                 }
 
                 #[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 posix01 {
                 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 struct stat {
                 }
 
                 #[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 posix01 {
                 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 struct stat {
                 }
 
                 #[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 bsd44 {}
             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 posix01 {
                 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 struct stat {
                 }
 
                 #[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 bsd44 {
             }
             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 posix01 {
                 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 struct glob_t {
                 }
 
                 #[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 bsd44 {
                 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 struct sockaddr_storage {
                     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 struct sockaddr_in {
                     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 struct sockaddr_in6 {
                     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 struct addrinfo {
                     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 posix01 {
                 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 struct stat {
                 }
 
                 #[repr(C)]
-                pub struct utimbuf {
+                #[deriving(Copy)] pub struct utimbuf {
                     pub actime: time_t,
                     pub modtime: time_t,
                 }
@@ -1056,7 +1062,7 @@ pub mod posix01 {
                 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 struct glob_t {
                 }
 
                 #[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 bsd44 {
                 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 struct sockaddr_storage {
                     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 struct sockaddr_in {
                     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 struct sockaddr_in6 {
                     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 struct addrinfo {
                     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 posix01 {
                 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 struct stat {
                     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 posix01 {
                 // 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 struct stat {
 
                 // 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 bsd44 {
                 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 struct sockaddr_in6 {
                     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 struct addrinfo {
                     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 extra {
                 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 struct SECURITY_ATTRIBUTES {
                 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 struct STARTUPINFO {
                 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 struct PROCESS_INFORMATION {
                 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 struct SYSTEM_INFO {
                 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 struct MEMORY_BASIC_INFORMATION {
                 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 struct OVERLAPPED {
                 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 struct FILETIME {
                 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 struct GUID {
                 }
 
                 #[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 struct WSAPROTOCOLCHAIN {
                 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 struct WSAPROTOCOL_INFO {
                 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 os {
         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 struct glob_t {
                 }
 
                 #[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 bsd44 {
                 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 struct sockaddr_in6 {
                     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 struct addrinfo {
                     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 posix01 {
                 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 struct stat {
                 }
 
                 #[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 bsd44 {
             }
             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 posix01 {
                 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 struct stat {
                 }
 
                 #[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 bsd44 {
             }
             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 winsock {
 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;
+}
index 5642ec91ba3b40d77c1ca5f765ce7b13e2b82eb6..8b79078eac6ad1548f53f6434bf22588138ea30b 100644 (file)
@@ -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.
index 2693f183644309c3454c1ebd503c9b7a569d56fb..ad5884c16c5c1b00c8c8aea3be03ac1f34be1919 100644 (file)
@@ -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],
@@ -115,7 +117,7 @@ pub fn set_counter(&mut self, counter_low: u64, counter_high: u64) {
     /// security proof for a more involved example of this.
     ///
     /// The modified word layout is:
-    /// ```notrust
+    /// ```ignore
     /// constant constant constant constant
     /// key      key      key      key
     /// key      key      key      key
index d874f1deed3c2194917becf96f942162121f6e16..9a9f31e9339c8e5240c693ab07e8320e8228f0a4 100644 (file)
@@ -10,6 +10,7 @@
 
 //! The exponential distribution.
 
+use core::kinds::Copy;
 use core::num::Float;
 
 use {Rng, Rand};
@@ -31,6 +32,8 @@
 /// College, Oxford
 pub struct Exp1(pub f64);
 
+impl Copy for Exp1 {}
+
 // This could be done via `-rng.gen::<f64>().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`.
index b3dc20819bc85a56463688579fdbb331c985086c..f5261f1db82ee7b7ca08ea03e8539fa29aa0beec 100644 (file)
@@ -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 @@
 /// College, Oxford
 pub struct StandardNormal(pub f64);
 
+impl Copy for StandardNormal {}
+
 impl Rand for StandardNormal {
     fn rand<R:Rng>(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.
index 517b50c49c7ef9478bad3459a7c15070f40a7025..2c1853b195151a2214c8536255fa3d85f8708212 100644 (file)
@@ -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],
index de40ee4893d56706c6acc1408c7c0a86a11ea13b..d357f247f1b74eb68a66329e68282ab5234bb06d 100644 (file)
@@ -377,6 +377,7 @@ pub trait SeedableRng<Seed>: 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.
     ///
index 64c6b1739ebb1f962468af06d88da8026cb268dd..88c870579e69002d40fe8fe3f0db849fa5ee1e4d 100644 (file)
@@ -135,6 +135,8 @@ pub trait Reseeder<R> {
 /// replacing the RNG with the result of a `Default::default` call.
 pub struct ReseedWithDefault;
 
+impl Copy for ReseedWithDefault {}
+
 impl<R: Rng + Default> Reseeder<R> for ReseedWithDefault {
     fn reseed(&mut self, rng: &mut R) {
         *rng = Default::default();
index f65c4f4e3edcc06cc890b90da0b5bc23b53eec62..426a987d25d1c535165da970919eadc4e602c744 100644 (file)
@@ -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 struct Res {
         pub next: uint
     }
 
+    impl Copy for Res {}
+
     #[inline(never)]
     fn vuint_at_slow(data: &[u8], start: uint) -> DecodeResult<Res> {
         let a = data[start];
index 5cd833e2797919b70046038c12c2fe8ea005dbcd..55e533aadee7ffc913f789f52570c2eacc872846 100644 (file)
@@ -83,6 +83,8 @@ pub enum Greed {
     Ungreedy,
 }
 
+impl Copy for Greed {}
+
 impl Greed {
     pub fn is_greedy(&self) -> bool {
         match *self {
index 58ce72a31736d517af3f624a70ca7d9b1dce0fb3..2a1fda06431c896944b9f40784fd6fae97cc896a 100644 (file)
@@ -135,8 +135,12 @@ pub struct ExNative {
     pub prog: fn(MatchKind, &str, uint, uint) -> Vec<Option<uint>>
 }
 
+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),
     }
 }
 
index 4315c0f7b404022cd65dcbfa38dea8d113497525..44cf2249b8e9b836f7e7cd126e8f97592416584e 100644 (file)
@@ -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 {
index a964609e4e63404b928e95528f853c1ace0f3c23..2af6a4876299b69ba043106133179764f06d39ad 100644 (file)
@@ -88,6 +88,7 @@ pub mod middle {
     pub mod privacy;
     pub mod reachable;
     pub mod region;
+    pub mod recursion_limit;
     pub mod resolve;
     pub mod resolve_lifetime;
     pub mod stability;
index c474820c3c934e5cd9f054642b854fb39628379e..e19fa01b2e4e88866385374969884ef4d648bd6f 100644 (file)
@@ -28,6 +28,7 @@
 
 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};
 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 @@
 
 pub struct WhileTrue;
 
+impl Copy for WhileTrue {}
+
 impl LintPass for WhileTrue {
     fn get_lints(&self) -> LintArray {
         lint_array!(WHILE_TRUE)
@@ -75,6 +79,8 @@ fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
 
 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 @@ fn visit_ty(&mut self, ty: &ast::Ty) {
 
 pub struct ImproperCTypes;
 
+impl Copy for ImproperCTypes {}
+
 impl LintPass for ImproperCTypes {
     fn get_lints(&self) -> LintArray {
         lint_array!(IMPROPER_CTYPES)
@@ -454,6 +464,8 @@ fn check_foreign_fn(cx: &Context, decl: &ast::FnDecl) {
 
 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 @@ fn check_item(&mut self, cx: &Context, item: &ast::Item) {
 
 pub struct UnusedAttributes;
 
+impl Copy for UnusedAttributes {}
+
 impl LintPass for UnusedAttributes {
     fn get_lints(&self) -> LintArray {
         lint_array!(UNUSED_ATTRIBUTES)
@@ -666,6 +680,8 @@ fn check_attribute(&mut self, cx: &Context, attr: &ast::Attribute) {
 
 pub struct PathStatements;
 
+impl Copy for PathStatements {}
+
 impl LintPass for PathStatements {
     fn get_lints(&self) -> LintArray {
         lint_array!(PATH_STATEMENTS)
@@ -693,6 +709,8 @@ fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
 
 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 @@ fn check_must_use(cx: &Context, attrs: &[ast::Attribute], sp: Span) -> bool {
 
 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 @@ fn method_context(cx: &Context, m: &ast::Method) -> MethodContext {
 
 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 @@ fn check_struct_def(&mut self, cx: &Context, s: &ast::StructDef,
 
 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 @@ fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
 
 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 @@ fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
 
 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 @@ fn check_view_item(&mut self, cx: &Context, view_item: &ast::ViewItem) {
 
 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 @@ fn check_pat(&mut self, cx: &Context, pat: &ast::Pat) {
 
 pub struct UnusedUnsafe;
 
+impl Copy for UnusedUnsafe {}
+
 impl LintPass for UnusedUnsafe {
     fn get_lints(&self) -> LintArray {
         lint_array!(UNUSED_UNSAFE)
@@ -1209,6 +1241,8 @@ fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
 
 pub struct UnsafeBlocks;
 
+impl Copy for UnsafeBlocks {}
+
 impl LintPass for UnsafeBlocks {
     fn get_lints(&self) -> LintArray {
         lint_array!(UNSAFE_BLOCKS)
@@ -1229,6 +1263,8 @@ fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
 
 pub struct UnusedMut;
 
+impl Copy for UnusedMut {}
+
 impl UnusedMut {
     fn check_unused_mut_pat(&self, cx: &Context, pats: &[P<ast::Pat>]) {
         // collect all mutable pattern and group their NodeIDs by their Identifier to
@@ -1294,6 +1330,8 @@ fn check_fn(&mut self, cx: &Context,
 
 pub struct UnusedAllocation;
 
+impl Copy for UnusedAllocation {}
+
 impl LintPass for UnusedAllocation {
     fn get_lints(&self) -> LintArray {
         lint_array!(UNUSED_ALLOCATION)
@@ -1479,6 +1517,61 @@ fn check_variant_post(&mut self, _: &Context, _: &ast::Variant, _: &ast::Generic
     }
 }
 
+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,
+                                      &parameter_environment) {
+            return
+        }
+        if ty::can_type_implement_copy(cx.tcx,
+                                       ty,
+                                       &parameter_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 @@ fn check_variant_post(&mut self, _: &Context, _: &ast::Variant, _: &ast::Generic
 /// `#[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 @@ fn check_item(&mut self, cx: &Context, item: &ast::Item) {
 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!(
index 442d3aab92dba9d562ba7e18462e2e0c14cf7b93..153a00e56177637caf88b220f08747fbdccdc462 100644 (file)
@@ -204,6 +204,7 @@ macro_rules! add_lint_group ( ( $sess:ident, $name:expr, $($lint:ident),* ) => (
                      UnusedMut,
                      UnusedAllocation,
                      Stability,
+                     MissingCopyImplementations,
         )
 
         add_builtin_with_new!(sess,
index d6b83752cc50cc7c0f624f13f4e0045f5587c714..4b4ba2ab94cd25a8e9d7e63fe92736233af32fd7 100644 (file)
@@ -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;
index 0da3b1b7a4e3e7b95cc425be893e509fe4514b1b..315e0eea9b763efe21221a80bb3716b6cbd11485 100644 (file)
@@ -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 {
index deeab18de7c139cb51ce59acc5bd8513269eb248..9e87153e64a1580d71faaf8dcb025a202a37e88f 100644 (file)
@@ -275,8 +275,10 @@ fn visit_item(e: &Env, i: &ast::Item) {
     }
 }
 
-fn register_native_lib(sess: &Session, span: Option<Span>, name: String,
-                       kind: cstore::NativeLibaryKind) {
+fn register_native_lib(sess: &Session,
+                       span: Option<Span>,
+                       name: String,
+                       kind: cstore::NativeLibraryKind) {
     if name.is_empty() {
         match span {
             Some(span) => {
index ebf5cca6a31a306520ad5f89497bf3a7c0e1859e..b864dc39603644486733f83ab58570fc2a41a75d 100644 (file)
@@ -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)
 }
index f93a1699e182d73f03553b5c78d25f0c4f19b441..bb1c75b075c2b2f3ce2e24d74cab849ec00b36ad 100644 (file)
@@ -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<NodeMap<ast::CrateNum>>,
     used_crate_sources: RefCell<Vec<CrateSource>>,
-    used_libraries: RefCell<Vec<(String, NativeLibaryKind)>>,
+    used_libraries: RefCell<Vec<(String, NativeLibraryKind)>>,
     used_link_args: RefCell<Vec<String>>,
     pub intr: Rc<IdentInterner>,
 }
@@ -186,13 +190,14 @@ fn visit(cstore: &CStore, cnum: ast::CrateNum,
         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<Vec<(String, NativeLibaryKind)> > {
+                              -> &'a RefCell<Vec<(String,
+                                                  NativeLibraryKind)>> {
         &self.used_libraries
     }
 
@@ -226,9 +231,18 @@ pub fn hash(&self) -> Svh { decoder::get_crate_hash(self.data()) }
 
 impl MetadataBlob {
     pub fn as_slice<'a>(&'a self) -> &'a [u8] {
-        match *self {
+        let slice = match *self {
             MetadataVec(ref vec) => vec.as_slice(),
             MetadataArchive(ref ar) => ar.as_slice(),
+        };
+        if slice.len() < 4 {
+            &[]
+        } else {
+            let len = ((slice[0] as u32) << 24) |
+                      ((slice[1] as u32) << 16) |
+                      ((slice[2] as u32) << 8) |
+                      ((slice[3] as u32) << 0);
+            slice.slice(4, len as uint + 4)
         }
     }
 }
index f352a28df6972e3b9690759c5b7720711993b61b..0d51e044de9cc2015df1df1b944448b7de107ece 100644 (file)
@@ -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));
index 3a111a3223b686446f320d771bada7f6b7f2cd87..a3f56f7f655f5ee31d787254bc5916ab617c95a5 100644 (file)
@@ -1979,7 +1979,32 @@ fn encode_dylib_dependency_formats(rbml_w: &mut Encoder, ecx: &EncodeContext) {
 pub fn encode_metadata(parms: EncodeParams, krate: &ast::Crate) -> Vec<u8> {
     let mut wr = SeekableMemWriter::new();
     encode_metadata_inner(&mut wr, parms, krate);
-    wr.unwrap().into_iter().collect()
+    let mut v = wr.unwrap();
+
+    // And here we run into yet another obscure archive bug: in which metadata
+    // loaded from archives may have trailing garbage bytes. Awhile back one of
+    // our tests was failing sporadially on the OSX 64-bit builders (both nopt
+    // and opt) by having rbml generate an out-of-bounds panic when looking at
+    // metadata.
+    //
+    // Upon investigation it turned out that the metadata file inside of an rlib
+    // (and ar archive) was being corrupted. Some compilations would generate a
+    // metadata file which would end in a few extra bytes, while other
+    // compilations would not have these extra bytes appended to the end. These
+    // extra bytes were interpreted by rbml as an extra tag, so they ended up
+    // being interpreted causing the out-of-bounds.
+    //
+    // The root cause of why these extra bytes were appearing was never
+    // discovered, and in the meantime the solution we're employing is to insert
+    // the length of the metadata to the start of the metadata. Later on this
+    // will allow us to slice the metadata to the precise length that we just
+    // generated regardless of trailing bytes that end up in it.
+    let len = v.len() as u32;
+    v.insert(0, (len >>  0) as u8);
+    v.insert(0, (len >>  8) as u8);
+    v.insert(0, (len >> 16) as u8);
+    v.insert(0, (len >> 24) as u8);
+    return v;
 }
 
 fn encode_metadata_inner(wr: &mut SeekableMemWriter,
index 63fc2af492cb0de4ea94f694113c91d797495aa9..2d23a61813a9c2a4d9223cf5cb468967c475218a 100644 (file)
 
 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
index 14b1eea2eb819714e88ce5d43cc45b55f48947f1..77c0a8abe6466cdfb50485c55ead831e916ba313 100644 (file)
 //!
 //! The compiler accepts a flag of this form a number of times:
 //!
-//! ```notrust
+//! ```ignore
 //! --extern crate-name=path/to/the/crate.rlib
 //! ```
 //!
 //!
 //! and the compiler would be invoked as:
 //!
-//! ```notrust
+//! ```ignore
 //! rustc a.rs --extern b1=path/to/libb1.rlib --extern b2=path/to/libb2.rlib
 //! ```
 //!
 //! dependencies, not the upstream transitive dependencies. Consider this
 //! dependency graph:
 //!
-//! ```notrust
+//! ```ignore
 //! A.1   A.2
 //! |     |
 //! |     |
index 00d12ad6a382db814994f847996be223336d20bc..e29741fb4a1298d18df59ab82135958aabc6d983 100644 (file)
@@ -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;
 
index 72c6256dcb5182849c8d88c766824f48c3cacc78..5f030324d421e1fdf0efa587102e85b281c7a303 100644 (file)
@@ -24,7 +24,9 @@
 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: &param_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 @@ fn check_if_path_is_moved(&self,
                 use_kind,
                 &**lp,
                 the_move,
-                moved_lp);
+                moved_lp,
+                self.param_env);
             false
         });
     }
index edffe59fff59c4b8c652553d156f62237a6a3ad6..ca9d4b512b301d5bb86b41367c8c1f7019187a2d 100644 (file)
@@ -22,6 +22,7 @@
 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};
 
 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<Loan<'tcx>>, move_data::MoveData<'tcx>)
-{
+                                    -> (Vec<Loan<'tcx>>,
+                                        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);
     }
 
index a209b1a28f284427d55ab48f282c3a944901dfe0..32fa5f8c3a9f2063767850031a69888bacbbb047 100644 (file)
@@ -34,6 +34,8 @@ pub enum Variant {
     Assigns,
 }
 
+impl Copy for Variant {}
+
 impl Variant {
     pub fn short_name(&self) -> &'static str {
         match *self {
index 0bbcdfe61bb46c86d5688ad0f81c0e16c177ecab..e90de1b69120453e797aa95b6c5cba86fbce2397 100644 (file)
@@ -25,7 +25,7 @@
 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 @@ macro_rules! if_ok(
 #[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<Rc<LoanPath<'tcx>>> {
 
 // 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 @@ pub fn report_use_of_moved_value(&self,
                                      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 @@ pub fn report_use_of_moved_value(&self,
                                                   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 @@ pub fn report_use_of_moved_value(&self,
                                                   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 @@ pub fn report_use_of_moved_value(&self,
             }
         }
 
-        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 @@ fn move_suggestion<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'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,
index 7bf3458f0ae3da3613273ea5e9ca6afa1c791574..3bb6145c5ca34ad5634c183133eb808420166bcc 100644 (file)
@@ -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 @@ fn clone(&self) -> 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 {
index 90919609e2e447ab72535ff461866ef2b709e55a..0dcb78f6bb04c3e7100deb322a1993f403a67a99 100644 (file)
@@ -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();
index a2e8ba8d65c3321e782a147b6512973a74c8c71d..bc512a73a4bd8af664038b90f72c71e8a28995b8 100644 (file)
@@ -30,6 +30,8 @@ pub struct CFGNodeData {
     pub id: ast::NodeId
 }
 
+impl Copy for CFGNodeData {}
+
 pub struct CFGEdgeData {
     pub exiting_scopes: Vec<ast::NodeId>
 }
index 36742df98503190a0dd2e40570259ad0fe17f1d8..eb073e07b02f1429eac02989b277867d3d89d1d9 100644 (file)
@@ -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)
 }
index ed119081f78c7913a3a840d368c37b5e6c415d73..2c437ae046b46deee7f56efc4b3164e5c364dabb 100644 (file)
@@ -99,7 +99,8 @@ fn from_iter<T: Iterator<Vec<&'a Pat>>>(iterator: T) -> 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 @@ fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v ast::FnDecl,
 }
 
 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);
 }
 
index dae76ba125e60f62ef32b77f5d792a16ebaa5dcf..a14307b90ee837f21677e48f508a9fa1f7e3784b 100644 (file)
@@ -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 @@ fn visit_fn(&mut self,
                 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)
index 2fc85afd3935d365f1d1b7f461fcf76a26ea6db9..a495d1e049d17601ac8386d4983d27de20dbfe6d 100644 (file)
@@ -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 @@ fn visit_expr(&mut self, e: &ast::Expr) {
     }
 }
 
-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) |
index 43726f55bb989ae2ae2167b2dc2efff4c7af486a..150bcbdd6886783fdb14aca98e8c95f086ce803c 100644 (file)
@@ -68,6 +68,8 @@ pub enum constness {
     non_const
 }
 
+impl Copy for constness {}
+
 type constness_cache = DefIdMap<constness>;
 
 pub fn join(a: constness, b: constness) -> constness {
index 53fea8ffc86c65e1f7519d5880fbf11cf0ed7f58..db8fd999f380bb605ae596189e46aadd3891d48b 100644 (file)
 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> {
index 4a4298f62f226bb2f331e768efb6d36dfe779804..b3e4dd25adc7aaa78a0e6956dd85c7d5bd8c4b1c 100644 (file)
@@ -52,6 +52,8 @@ pub enum Def {
     DefMethod(ast::DefId /* method */, Option<ast::DefId> /* trait */, MethodProvenance),
 }
 
+impl Copy for Def {}
+
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum MethodProvenance {
     FromTrait(ast::DefId),
@@ -67,6 +69,8 @@ pub fn map(self, f: |ast::DefId| -> ast::DefId) -> MethodProvenance {
     }
 }
 
+impl Copy for MethodProvenance {}
+
 impl Def {
     pub fn def_id(&self) -> ast::DefId {
         match *self {
index dbec69f420503f139efa1facf2863bfb5c321f86..8bf43c70c26d91cac9af4cb4cf39c6dd4b2ea2db 100644 (file)
@@ -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,
index 7d2bb7458acd59cd197bc09d8c09d59f91de7bdc..8e00c96535b1e2c79a54db5491c85753f4ddcde0 100644 (file)
 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<T> {
-    Unknown, Definite(MatchMode), Conflicting,
+    Unknown,
+    Definite(MatchMode),
+    Conflicting,
 }
 
+impl<T> kinds::Copy for TrackMatchMode<T> {}
+
 impl<T> TrackMatchMode<T> {
     // 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 @@ fn delegate_consume(&mut self,
                         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 @@ fn determine_pat_move_mode(&mut self,
                     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 @@ fn walk_pat(&mut self,
         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 @@ fn walk_pat(&mut self,
                                              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 @@ fn walk_by_value_captures(&mut self,
             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 @@ fn cat_captured_var(&mut self,
     }
 }
 
-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
+    }
 }
 
index 888f01f9118fa9563c8799042c88d7119797b3ba..6780177933fd1179ea1bc9e23bdb32c8b53094f3 100644 (file)
@@ -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.
index 2f50a96402302a5354aa540095006dcde08c53f2..e45232a3c303879ef35972346e07e4fccc240f0a 100644 (file)
@@ -65,11 +65,15 @@ fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
 #[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 struct Direction { repr: uint }
 #[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).
index c5845b143af89aca4da0d3ee6b563e498d094543..81cd8dd20d20c6c0761a8b403feac54817941c4f 100644 (file)
@@ -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(_) => {
index 9155c18cb3b5a1dea04bc75f165e1bcfbda99578..391e37e8b9c965398612b8b206aeca67e902a46f 100644 (file)
@@ -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 @@ fn intersect_scopes(&self,
 #[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,
index 3058f09a83a851d5006d846f6f1e3ddbf9aaed6f..766e930486ca2de76b1a0cc7c0e9ffbb149d38ac 100644 (file)
@@ -49,6 +49,8 @@ pub enum RelationDir {
     SubtypeOf, SupertypeOf, EqTo
 }
 
+impl Copy for RelationDir {}
+
 impl RelationDir {
     fn opposite(self) -> RelationDir {
         match self {
index 6f6adb84a75f524d879bb40d33c0c6b6b11f2932..a2dd4d62913523a33c3231bbb9b5ea00bbbb3dca 100644 (file)
@@ -92,6 +92,8 @@ pub struct Node<K,V> {
 
 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<U> for some
 // other type parameter U, and we have no way to say
index da1c0bd649a16c78e4888e9d817984842f7e34cc..4a20c92d8e21e5bc3002b61e6b1b6dc0a1301ae0 100644 (file)
@@ -50,6 +50,8 @@ pub enum LangItem {
     $($variant),*
 }
 
+impl Copy for LangItem {}
+
 pub struct LanguageItems {
     pub items: Vec<Option<ast::DefId>>,
     pub missing: Vec<LangItem>,
index a6d3c15df8a7488ff7d37c1b0537b0bafc41846f..5edbafc4e0bee4e7bf47b95451662c20b364f892 100644 (file)
@@ -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;
index cd70d8e2b487adb4d39b69805d3fde44b54f3229..302fbd53dd5302f1fce3a6daa4738ba997967614 100644 (file)
@@ -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<T> = Result<T, ()>;
 
 /// 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/recursion_limit.rs b/src/librustc/middle/recursion_limit.rs
new file mode 100644 (file)
index 0000000..a6a6703
--- /dev/null
@@ -0,0 +1,39 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Recursion limit.
+//
+// There are various parts of the compiler that must impose arbitrary limits
+// on how deeply they recurse to prevent stack overflow. Users can override
+// this via an attribute on the crate like `#![recursion_limit(22)]`. This pass
+// just peeks and looks for that attribute.
+
+use session::Session;
+use syntax::ast;
+use syntax::attr::AttrMetaMethods;
+use std::str::FromStr;
+
+pub fn update_recursion_limit(sess: &Session, krate: &ast::Crate) {
+    for attr in krate.attrs.iter() {
+        if !attr.check_name("recursion_limit") {
+            continue;
+        }
+
+        if let Some(s) = attr.value_str() {
+            if let Some(n) = FromStr::from_str(s.get()) {
+                sess.recursion_limit.set(n);
+                return;
+            }
+        }
+
+        sess.span_err(attr.span, "malformed recursion limit attribute, \
+                                  expected #![recursion_limit(\"N\")]");
+    }
+}
index 2b8dd8df249816452cc5e9d659da15f740fc6410..370097004e92c54d5b445c662d741cd7ae7307a3 100644 (file)
@@ -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<ast::NodeId>,
 }
 
+impl Copy for Context {}
+
 struct RegionResolutionVisitor<'a> {
     sess: &'a Session,
 
index 8c3aa22c5fcf9af8521dd47446e8588baefa3c97..36b87bbd42392081592acb0511a5ee165130eee3 100644 (file)
@@ -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<Name,binding_info>;
 
@@ -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<Module>, 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<Name, DefLike>,
@@ -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 @@ fn all_imports_resolved(&self) -> bool {
     }
 }
 
+impl Copy for DefModifiers {}
+
 // Records a possibly-private type definition.
 #[deriving(Clone)]
 struct TypeNsDef {
@@ -616,6 +652,8 @@ struct ValueNsDef {
     value_span: Option<Span>,
 }
 
+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,                      // <T as SomeTrait>::
 }
 
+impl Copy for TraitReferenceType {}
+
 impl NameBindings {
     fn new() -> NameBindings {
         NameBindings {
index bd8db1d51dfd5b321eda48613bc361d4c0b346c9..2ba9ba5631d6a5aa41bacc43b6123dc9e8dc0692 100644 (file)
@@ -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<DefRegion>;
index 21f57a9d57388a9d8741abaa76abbdca4e54fbf7..bcc762a9640f7310e12baca0b047d5f78b7981cc 100644 (file)
@@ -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]
index e12ec44ad87cec3c37a86829d4db8fbce663edaf..d410a456dc913d01e8df8853c13a12daae78e7cd 100644 (file)
@@ -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<Obligation<'tcx>>;
 
+impl<'tcx> Copy for ObligationCauseCode<'tcx> {}
+
 pub type Selection<'tcx> = Vtable<'tcx, Obligation<'tcx>>;
 
 #[deriving(Clone,Show)]
@@ -338,7 +342,7 @@ pub fn map_nested<M>(&self, op: |&N| -> M) -> Vtable<'tcx, M> {
             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 @@ pub fn map_move_nested<M>(self, op: |N| -> M) -> Vtable<'tcx, M> {
             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)),
         }
     }
 }
index 0e6a0c19f70611e7758f1bbc56937b95a11a0e4f..06f8cbf1a6a60e88b02770b4c24d879580b0541c 100644 (file)
@@ -80,6 +80,7 @@ struct ObligationStack<'prev, 'tcx: 'prev> {
     previous: Option<&'prev ObligationStack<'prev, 'tcx>>
 }
 
+#[deriving(Clone)]
 pub struct SelectionCache<'tcx> {
     hashmap: RefCell<HashMap<Rc<ty::TraitRef<'tcx>>,
                              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
@@ -155,10 +158,10 @@ enum BuiltinBoundConditions<'tcx> {
 }
 
 #[deriving(Show)]
-enum EvaluationResult {
+enum EvaluationResult<'tcx> {
     EvaluatedToOk,
-    EvaluatedToErr,
     EvaluatedToAmbig,
+    EvaluatedToErr(SelectionError<'tcx>),
 }
 
 impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
@@ -272,7 +275,7 @@ fn evaluate_builtin_bound_recursively<'o>(&mut self,
                                               bound: ty::BuiltinBound,
                                               previous_stack: &ObligationStack<'o, 'tcx>,
                                               ty: Ty<'tcx>)
-                                              -> EvaluationResult
+                                              -> EvaluationResult<'tcx>
     {
         let obligation =
             util::obligation_for_builtin_bound(
@@ -295,7 +298,7 @@ fn evaluate_builtin_bound_recursively<'o>(&mut self,
     fn evaluate_obligation_recursively<'o>(&mut self,
                                            previous_stack: Option<&ObligationStack<'o, 'tcx>>,
                                            obligation: &Obligation<'tcx>)
-                                           -> EvaluationResult
+                                           -> EvaluationResult<'tcx>
     {
         debug!("evaluate_obligation_recursively({})",
                obligation.repr(self.tcx()));
@@ -310,7 +313,7 @@ fn evaluate_obligation_recursively<'o>(&mut self,
 
     fn evaluate_stack<'o>(&mut self,
                           stack: &ObligationStack<'o, 'tcx>)
-                          -> EvaluationResult
+                          -> EvaluationResult<'tcx>
     {
         // In intercrate mode, whenever any of the types are unbound,
         // there can always be an impl. Even if there are no impls in
@@ -381,7 +384,7 @@ fn evaluate_stack<'o>(&mut self,
         match self.candidate_from_obligation(stack) {
             Ok(Some(c)) => self.winnow_candidate(stack, &c),
             Ok(None) => EvaluatedToAmbig,
-            Err(_) => EvaluatedToErr,
+            Err(e) => EvaluatedToErr(e),
         }
     }
 
@@ -412,285 +415,6 @@ pub fn evaluate_impl(&mut self,
         })
     }
 
-    ///////////////////////////////////////////////////////////////////////////
-    // METHOD MATCHING
-    //
-    // Method matching is a variation on the normal select/evaluation
-    // situation.  In this scenario, rather than having a full trait
-    // reference to select from, we start with an expression like
-    // `receiver.method(...)`. This means that we have `rcvr_ty`, the
-    // type of the receiver, and we have a possible trait that
-    // supplies `method`. We must determine whether the receiver is
-    // applicable, taking into account the transformed self type
-    // declared on `method`. We also must consider the possibility
-    // that `receiver` can be *coerced* into a suitable type (for
-    // example, a receiver type like `&(Any+Send)` might be coerced
-    // into a receiver like `&Any` to allow for method dispatch).  See
-    // the body of `evaluate_method_obligation()` for more details on
-    // the algorithm.
-
-    /// Determine whether a trait-method is applicable to a receiver of
-    /// type `rcvr_ty`. *Does not affect the inference state.*
-    ///
-    /// - `rcvr_ty` -- type of the receiver
-    /// - `xform_self_ty` -- transformed self type declared on the method, with `Self`
-    ///   to a fresh type variable
-    /// - `obligation` -- a reference to the trait where the method is declared, with
-    ///   the input types on the trait replaced with fresh type variables
-    pub fn evaluate_method_obligation(&mut self,
-                                      rcvr_ty: Ty<'tcx>,
-                                      xform_self_ty: Ty<'tcx>,
-                                      obligation: &Obligation<'tcx>)
-                                      -> MethodMatchResult
-    {
-        // Here is the situation. We have a trait method declared (say) like so:
-        //
-        //     trait TheTrait {
-        //         fn the_method(self: Rc<Self>, ...) { ... }
-        //     }
-        //
-        // And then we have a call looking (say) like this:
-        //
-        //     let x: Rc<Foo> = ...;
-        //     x.the_method()
-        //
-        // Now we want to decide if `TheTrait` is applicable. As a
-        // human, we can see that `TheTrait` is applicable if there is
-        // an impl for the type `Foo`. But how does the compiler know
-        // what impl to look for, given that our receiver has type
-        // `Rc<Foo>`? We need to take the method's self type into
-        // account.
-        //
-        // On entry to this function, we have the following inputs:
-        //
-        // - `rcvr_ty = Rc<Foo>`
-        // - `xform_self_ty = Rc<$0>`
-        // - `obligation = $0 as TheTrait`
-        //
-        // We do the match in two phases. The first is a *precise
-        // match*, which means that no coercion is required. This is
-        // the preferred way to match. It works by first making
-        // `rcvr_ty` a subtype of `xform_self_ty`. This unifies `$0`
-        // and `Foo`. We can then evaluate (roughly as normal) the
-        // trait reference `Foo as TheTrait`.
-        //
-        // If this fails, we fallback to a coercive match, described below.
-
-        match self.infcx.probe(|| self.match_method_precise(rcvr_ty, xform_self_ty, obligation)) {
-            Ok(()) => { return MethodMatched(PreciseMethodMatch); }
-            Err(_) => { }
-        }
-
-        // Coercive matches work slightly differently and cannot
-        // completely reuse the normal trait matching machinery
-        // (though they employ many of the same bits and pieces). To
-        // see how it works, let's continue with our previous example,
-        // but with the following declarations:
-        //
-        // ```
-        // trait Foo : Bar { .. }
-        // trait Bar : Baz { ... }
-        // trait Baz { ... }
-        // impl TheTrait for Bar {
-        //     fn the_method(self: Rc<Bar>, ...) { ... }
-        // }
-        // ```
-        //
-        // Now we see that the receiver type `Rc<Foo>` is actually an
-        // object type. And in fact the impl we want is an impl on the
-        // supertrait `Rc<Bar>`.  The precise matching procedure won't
-        // find it, however, because `Rc<Foo>` is not a subtype of
-        // `Rc<Bar>` -- it is *coercible* to `Rc<Bar>` (actually, such
-        // coercions are not yet implemented, but let's leave that
-        // aside for now).
-        //
-        // To handle this case, we employ a different procedure. Recall
-        // that our initial state is as follows:
-        //
-        // - `rcvr_ty = Rc<Foo>`
-        // - `xform_self_ty = Rc<$0>`
-        // - `obligation = $0 as TheTrait`
-        //
-        // We now go through each impl and instantiate all of its type
-        // variables, yielding the trait reference that the impl
-        // provides. In our example, the impl would provide `Bar as
-        // TheTrait`.  Next we (try to) unify the trait reference that
-        // the impl provides with the input obligation. This would
-        // unify `$0` and `Bar`. Now we can see whether the receiver
-        // type (`Rc<Foo>`) is *coercible to* the transformed self
-        // type (`Rc<$0> == Rc<Bar>`). In this case, the answer is
-        // yes, so the impl is considered a candidate.
-        //
-        // Note that there is the possibility of ambiguity here, even
-        // when all types are known. In our example, this might occur
-        // if there was *also* an impl of `TheTrait` for `Baz`. In
-        // this case, `Rc<Foo>` would be coercible to both `Rc<Bar>`
-        // and `Rc<Baz>`. (Note that it is not a *coherence violation*
-        // to have impls for both `Bar` and `Baz`, despite this
-        // ambiguity).  In this case, we report an error, listing all
-        // the applicable impls.  The user can explicitly "up-coerce"
-        // to the type they want.
-        //
-        // Note that this coercion step only considers actual impls
-        // found in the source. This is because all the
-        // compiler-provided impls (such as those for unboxed
-        // closures) do not have relevant coercions. This simplifies
-        // life immensely.
-
-        let mut impls =
-            self.assemble_method_candidates_from_impls(rcvr_ty, xform_self_ty, obligation);
-
-        if impls.len() > 1 {
-            impls.retain(|&c| self.winnow_method_impl(c, rcvr_ty, xform_self_ty, obligation));
-        }
-
-        if impls.len() > 1 {
-            return MethodAmbiguous(impls);
-        }
-
-        match impls.pop() {
-            Some(def_id) => MethodMatched(CoerciveMethodMatch(def_id)),
-            None => MethodDidNotMatch
-        }
-    }
-
-    /// Given the successful result of a method match, this function "confirms" the result, which
-    /// basically repeats the various matching operations, but outside of any snapshot so that
-    /// their effects are committed into the inference state.
-    pub fn confirm_method_match(&mut self,
-                                rcvr_ty: Ty<'tcx>,
-                                xform_self_ty: Ty<'tcx>,
-                                obligation: &Obligation<'tcx>,
-                                data: MethodMatchedData)
-    {
-        let is_ok = match data {
-            PreciseMethodMatch => {
-                self.match_method_precise(rcvr_ty, xform_self_ty, obligation).is_ok()
-            }
-
-            CoerciveMethodMatch(impl_def_id) => {
-                self.match_method_coerce(impl_def_id, rcvr_ty, xform_self_ty, obligation).is_ok()
-            }
-        };
-
-        if !is_ok {
-            self.tcx().sess.span_bug(
-                obligation.cause.span,
-                format!("match not repeatable: {}, {}, {}, {}",
-                        rcvr_ty.repr(self.tcx()),
-                        xform_self_ty.repr(self.tcx()),
-                        obligation.repr(self.tcx()),
-                        data)[]);
-        }
-    }
-
-    /// Implements the *precise method match* procedure described in
-    /// `evaluate_method_obligation()`.
-    fn match_method_precise(&mut self,
-                            rcvr_ty: Ty<'tcx>,
-                            xform_self_ty: Ty<'tcx>,
-                            obligation: &Obligation<'tcx>)
-                            -> Result<(),()>
-    {
-        self.infcx.commit_if_ok(|| {
-            match self.infcx.sub_types(false, infer::RelateSelfType(obligation.cause.span),
-                                       rcvr_ty, xform_self_ty) {
-                Ok(()) => { }
-                Err(_) => { return Err(()); }
-            }
-
-            if self.evaluate_obligation(obligation) {
-                Ok(())
-            } else {
-                Err(())
-            }
-        })
-    }
-
-    /// Assembles a list of potentially applicable impls using the *coercive match* procedure
-    /// described in `evaluate_method_obligation()`.
-    fn assemble_method_candidates_from_impls(&mut self,
-                                             rcvr_ty: Ty<'tcx>,
-                                             xform_self_ty: Ty<'tcx>,
-                                             obligation: &Obligation<'tcx>)
-                                             -> Vec<ast::DefId>
-    {
-        let mut candidates = Vec::new();
-
-        let all_impls = self.all_impls(obligation.trait_ref.def_id);
-        for &impl_def_id in all_impls.iter() {
-            self.infcx.probe(|| {
-                match self.match_method_coerce(impl_def_id, rcvr_ty, xform_self_ty, obligation) {
-                    Ok(_) => { candidates.push(impl_def_id); }
-                    Err(_) => { }
-                }
-            });
-        }
-
-        candidates
-    }
-
-    /// Applies the *coercive match* procedure described in `evaluate_method_obligation()` to a
-    /// particular impl.
-    fn match_method_coerce(&mut self,
-                           impl_def_id: ast::DefId,
-                           rcvr_ty: Ty<'tcx>,
-                           xform_self_ty: Ty<'tcx>,
-                           obligation: &Obligation<'tcx>)
-                           -> Result<Substs<'tcx>, ()>
-    {
-        // This is almost always expected to succeed. It
-        // causes the impl's self-type etc to be unified with
-        // the type variable that is shared between
-        // obligation/xform_self_ty. In our example, after
-        // this is done, the type of `xform_self_ty` would
-        // change from `Rc<$0>` to `Rc<Foo>` (because $0 is
-        // unified with `Foo`).
-        let substs = try!(self.match_impl(impl_def_id, obligation));
-
-        // Next, check whether we can coerce. For now we require
-        // that the coercion be a no-op.
-        let origin = infer::Misc(obligation.cause.span);
-        match infer::mk_coercety(self.infcx, true, origin,
-                                 rcvr_ty, xform_self_ty) {
-            Ok(None) => { /* Fallthrough */ }
-            Ok(Some(_)) | Err(_) => { return Err(()); }
-        }
-
-        Ok(substs)
-    }
-
-    /// A version of `winnow_impl` applicable to coerice method matching.  This is basically the
-    /// same as `winnow_impl` but it uses the method matching procedure and is specific to impls.
-    fn winnow_method_impl(&mut self,
-                          impl_def_id: ast::DefId,
-                          rcvr_ty: Ty<'tcx>,
-                          xform_self_ty: Ty<'tcx>,
-                          obligation: &Obligation<'tcx>)
-                          -> bool
-    {
-        debug!("winnow_method_impl: impl_def_id={} rcvr_ty={} xform_self_ty={} obligation={}",
-               impl_def_id.repr(self.tcx()),
-               rcvr_ty.repr(self.tcx()),
-               xform_self_ty.repr(self.tcx()),
-               obligation.repr(self.tcx()));
-
-        self.infcx.probe(|| {
-            match self.match_method_coerce(impl_def_id, rcvr_ty, xform_self_ty, obligation) {
-                Ok(substs) => {
-                    let vtable_impl = self.vtable_impl(impl_def_id,
-                                                       substs,
-                                                       obligation.cause,
-                                                       obligation.recursion_depth + 1);
-                    self.winnow_selection(None, VtableImpl(vtable_impl)).may_apply()
-                }
-                Err(()) => {
-                    false
-                }
-            }
-        })
-    }
-
     ///////////////////////////////////////////////////////////////////////////
     // CANDIDATE ASSEMBLY
     //
@@ -918,20 +642,38 @@ fn assemble_candidates<'o>(&mut self,
         // 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()));
+
+                // 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));
             }
 
             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)
     }
 
@@ -1091,14 +833,14 @@ fn assemble_candidates_from_impls(&mut self,
     fn winnow_candidate<'o>(&mut self,
                             stack: &ObligationStack<'o, 'tcx>,
                             candidate: &Candidate<'tcx>)
-                            -> EvaluationResult
+                            -> EvaluationResult<'tcx>
     {
         debug!("winnow_candidate: candidate={}", candidate.repr(self.tcx()));
         self.infcx.probe(|| {
             let candidate = (*candidate).clone();
             match self.confirm_candidate(stack.obligation, candidate) {
                 Ok(selection) => self.winnow_selection(Some(stack), selection),
-                Err(_) => EvaluatedToErr,
+                Err(error) => EvaluatedToErr(error),
             }
         })
     }
@@ -1106,12 +848,12 @@ fn winnow_candidate<'o>(&mut self,
     fn winnow_selection<'o>(&mut self,
                             stack: Option<&ObligationStack<'o, 'tcx>>,
                             selection: Selection<'tcx>)
-                            -> EvaluationResult
+                            -> EvaluationResult<'tcx>
     {
         let mut result = EvaluatedToOk;
         for obligation in selection.iter_nested() {
             match self.evaluate_obligation_recursively(stack, obligation) {
-                EvaluatedToErr => { return EvaluatedToErr; }
+                EvaluatedToErr(e) => { return EvaluatedToErr(e); }
                 EvaluatedToAmbig => { result = EvaluatedToAmbig; }
                 EvaluatedToOk => { }
             }
@@ -1519,12 +1261,11 @@ fn nominal<'cx, 'tcx>(this: &mut 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. 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)
                     }
                 }
 
@@ -2126,11 +1867,18 @@ fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
     }
 }
 
-impl EvaluationResult {
+impl<'tcx> EvaluationResult<'tcx> {
     fn may_apply(&self) -> bool {
         match *self {
-            EvaluatedToOk | EvaluatedToAmbig => true,
-            EvaluatedToErr => false,
+            EvaluatedToOk |
+            EvaluatedToAmbig |
+            EvaluatedToErr(Overflow) |
+            EvaluatedToErr(OutputTypeParameterMismatch(..)) => {
+                true
+            }
+            EvaluatedToErr(Unimplemented) => {
+                false
+            }
         }
     }
 }
index 8a2529701bbb38433001719f2253c6ab48ddfd3f..4c4b5d07f50ac21892065addc9bbd83954fa2ed4 100644 (file)
@@ -38,6 +38,7 @@
 pub use self::ExprAdjustment::*;
 pub use self::vtable_origin::*;
 pub use self::MethodOrigin::*;
+pub use self::CopyImplementationError::*;
 
 use back::svh::Svh;
 use session::Session;
 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::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::{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<Trait>
@@ -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<Variance>,
@@ -286,6 +307,8 @@ pub enum Variance {
     Bivariant,      // T<A> <: T<B>            -- 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<DefIdMap<Rc<Vec<attr::ReprAttr>>>>,
+
+    /// Caches whether types move by default.
+    pub type_moves_by_default_cache: RefCell<HashMap<Ty<'tcx>,bool>>,
 }
 
 // Flags that we track on types. These flags are propagated upwards
@@ -766,6 +800,8 @@ pub struct ctxt<'tcx> {
     }
 }
 
+impl Copy for TypeFlags {}
+
 #[deriving(Show)]
 pub struct TyS<'tcx> {
     pub sty: sty<'tcx>,
@@ -807,6 +843,7 @@ fn eq(&self, other: &InternedTy<'tcx>) -> bool {
         self.ty.sty == other.ty.sty
     }
 }
+
 impl<'tcx> Eq for InternedTy<'tcx> {}
 
 impl<'tcx, S: Writer> Hash<S> for InternedTy<'tcx> {
@@ -900,6 +937,8 @@ pub fn unwrap(self) -> Ty<'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<UpvarId, UpvarBorrow>;
 
+impl Copy for UpvarBorrow {}
+
 impl Region {
     pub fn is_bound(&self) -> bool {
         match *self {
@@ -1136,6 +1183,8 @@ pub fn escapes_depth(&self, depth: uint) -> bool {
     }
 }
 
+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<T> {
     pub expected: T,
     pub found: T
 }
 
+impl<T:Copy> Copy for expected_found<T> {}
+
 // 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<bool>)
 }
 
+impl<'tcx> Copy for type_err<'tcx> {}
+
 /// Bounds suitable for a named type parameter like `A` in `fn foo<A>`
 /// 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<BuiltinBound>;
 
 #[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 @@ pub fn has_bound_regions(&self) -> bool {
 /// 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 @@ pub fn for_item(cx: &ctxt<'tcx>, id: NodeId) -> 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 @@ pub fn for_item(cx: &ctxt<'tcx>, id: NodeId) -> 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 @@ pub fn for_item(cx: &ctxt<'tcx>, id: NodeId) -> 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 @@ pub fn for_item(cx: &ctxt<'tcx>, id: NodeId) -> 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 @@ mod TC {
         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 @@ mod TC {
         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 @@ pub fn interior_unsized(&self) -> bool {
         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 @@ fn tc_mt<'tcx>(cx: &ctxt<'tcx>,
         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 @@ fn borrowed_contents(region: ty::Region,
                          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 @@ fn closure_contents(cx: &ctxt, cty: &ClosureTy) -> 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 @@ fn kind_bounds_to_contents<'tcx>(cx: &ctxt<'tcx>,
         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 @@ fn each_inherited_builtin_bound<'tcx>(cx: &ctxt<'tcx>,
     }
 }
 
-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<Ordering> {
         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<UnboxedClosureUpvar<'tcx>> {
@@ -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<Vec<Freevar>>;
 
 pub type CaptureModeMap = NodeMap<ast::CaptureClause>;
@@ -6122,6 +6223,8 @@ pub fn shifted(&self, amount: uint) -> 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(())
+}
index 981b58a3b7be1ff0bfd6083ddeeeb20ac9118071..c7b5e1e8de9a5a629c59a01e9da82ebf07a74995 100644 (file)
@@ -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<Vec<Path>>,
-    pub libs: Vec<(String, cstore::NativeLibaryKind)>,
+    pub libs: Vec<(String, cstore::NativeLibraryKind)>,
     pub maybe_sysroot: Option<Path>,
     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;
index ea252d9fd205c99d0abac30fdc05648ee4f9c24f..30318cc129cacb2ef1f7f36af510bee471d16873 100644 (file)
@@ -25,6 +25,8 @@
 #[deriving(Clone,Show)]
 pub struct ErrorReported;
 
+impl Copy for ErrorReported {}
+
 pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T {
     thread_local!(static DEPTH: Cell<uint> = Cell::new(0));
     if !do_it { return f(u); }
index 4dd6306c3c096764903348ddb9f53fa9afdb738b..d1816c655fa5fef0e22057b826a9e9c32334933e 100644 (file)
@@ -71,6 +71,9 @@ pub fn new() -> super::DefIdSet {
 #[deriving(Clone, Default)]
 pub struct FnvHasher;
 
+impl Copy for FnvHasher {}
+
+#[allow(missing_copy_implementations)]
 pub struct FnvState(u64);
 
 impl Hasher<FnvState> for FnvHasher {
index f3d76a8f12f1f38f37b80d4b8293a24e1586156b..749bed15e38e05cc05a4c293d35f667327f1fed3 100644 (file)
@@ -180,6 +180,10 @@ pub fn phase_2_configure_and_expand(sess: &Session,
         *sess.features.borrow_mut() = features;
     });
 
+    time(time_passes, "recursion limit", (), |_| {
+        middle::recursion_limit::update_recursion_limit(sess, &krate);
+    });
+
     // strip before expansion to allow macros to depend on
     // configuration variables e.g/ in
     //
index b6441ab4944f7da76e7e6ab8bdc6da20f866a173..d143d05acfe4b9b5ec05c489e0e1ff34398d02bf 100644 (file)
@@ -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<UserIdentifiedItem>) {
     let mut split = name.splitn(1, '=');
     let first = split.next().unwrap();
index d705c82dd9a471151046995de1c8712f901b050f..04196feafd22b525be2fec61daa6c89508cfa2f8 100644 (file)
@@ -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);
index a8211c0c9eae185d07b982059c388efa398084e0..23dad21e5303f8c179e64f992243d30c244a7178 100644 (file)
@@ -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 @@ pub enum DiagnosticSeverity {
     }
 }
 
+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 enum DIDescriptorFlags {
       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<Vec<u8>>;
index a919fe686abfc955e583b5cd92728ee1c026c1b5..0ed6ae311711fc747b79cd4ddbcdb1f37a5138da 100644 (file)
 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();
index 1482422b8d03eecfd22db5a6753ac9b58e96aae7..2a698a898fe871a91d390def4097447100eafc28 100644 (file)
@@ -249,7 +249,7 @@ fn process_formals(&mut self, formals: &Vec<ast::Arg>, qualname: &str) {
             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]);
index f0bb441145cc282172ae3513011d8f7875643ee4..c15ff1d7f0a9d2fc00098d5766dc64ae6be60446 100644 (file)
@@ -87,6 +87,8 @@ pub enum Row {
     FnRef,
 }
 
+impl Copy for Row {}
+
 impl<'a> FmtStrs<'a> {
     pub fn new(rec: Box<Recorder>, span: SpanUtils<'a>, krate: String) -> FmtStrs<'a> {
         FmtStrs {
@@ -223,7 +225,10 @@ pub fn record_with_span(&mut self,
 
         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;
         }
index f76f2bea5668f4f912a0eb9b03b1738c0617f43a..49e8e0fd3471421f3640ae12a866662a6d00e7a7 100644 (file)
@@ -21,6 +21,7 @@
 use syntax::parse::token;
 use syntax::parse::token::{keywords, Token};
 
+#[deriving(Clone)]
 pub struct SpanUtils<'a> {
     pub sess: &'a Session,
     pub err_count: Cell<int>,
index f5155852aa00c5850980791e1a2fb8741e9d3427..1ed06938e95c878e8fcc1044aa6465676bb81105 100644 (file)
 #[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<Ident, BindingInfo<'tcx>>;
 
 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,
+                                              &param_env) || reassigned => {
                 llmatch = alloca_no_lifetime(bcx,
                                  llvariable_ty.ptr_to(),
                                  "__llmatch");
index 2f0f373325a01b457e901c7e40879e5ca9c492b8..e273a56ce025b2b33f616b4f63cbde4373ab833a 100644 (file)
@@ -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
     }
 
index 3090119788c32cb647d91a5279d1da08fa6a52f0..cef12616cf267178b2301fc5c196488ffdd02afc 100644 (file)
@@ -90,6 +90,7 @@
 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 @@ fn iter_variant<'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 @@ impl Iterator<ValueRef> for ValueIter {
         fn next(&mut self) -> Option<ValueRef> {
             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
index 328c8e616c40b945d6aef7dbfbbebb633b429fd4..b55c268d9a909d22191bcb726012a559a34b9932 100644 (file)
@@ -15,6 +15,8 @@
 
 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
index 518b0ba73f8b745744f5010384768bb5b11786e1..7aabd998f7aaeac5cd2021ce8735ede3d2c1c7e7 100644 (file)
@@ -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<Attribute>
 }
 
+impl Copy for ArgType {}
+
 impl ArgType {
     pub fn direct(ty: Type, cast: option::Option<Type>,
                             pad: option::Option<Type>,
index 69ee5301d18bf03be001d6c6e20da8567b3dab36..00c91ddebb38ebf31331f1974d1f0bbbd534c95e 100644 (file)
@@ -40,6 +40,8 @@ enum RegClass {
     Memory
 }
 
+impl Copy for RegClass {}
+
 trait TypeMethods {
     fn is_reg_ty(&self) -> bool;
 }
index 746109ef1134690d2edf704d9832a3f77834383f..ff7ab91c39a58edbecc42b4d0466b96eb97937fa 100644 (file)
@@ -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>,
index 33393ba76c58059805995150b066770c6d39d8a9..ba3e70fe036fc475720784055f64b2c34b82cf23 100644 (file)
@@ -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
index bb4df00bd944a1147ed9f6504767897d6a4b2082..1811388662c45f1ef4e77d897b3b3b582964c3c5 100644 (file)
@@ -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))
@@ -286,7 +288,6 @@ fn load_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             debuginfo::create_captured_var_metadata(
                 bcx,
                 def_id.node,
-                cdata_ty,
                 env_pointer_alloca,
                 i,
                 captured_by_ref,
@@ -326,7 +327,7 @@ fn load_unboxed_closure_environment<'blk, 'tcx>(
     // Store the pointer to closure data in an alloca for debug info because that's what the
     // llvm.dbg.declare intrinsic expects
     let env_pointer_alloca = if bcx.sess().opts.debuginfo == FullDebugInfo {
-        let alloc = alloc_ty(bcx, ty::mk_mut_ptr(bcx.tcx(), self_type), "__debuginfo_env_ptr");
+        let alloc = alloca(bcx, val_ty(llenv), "__debuginfo_env_ptr");
         Store(bcx, llenv, alloc);
         Some(alloc)
     } else {
@@ -355,7 +356,6 @@ fn load_unboxed_closure_environment<'blk, 'tcx>(
             debuginfo::create_captured_var_metadata(
                 bcx,
                 def_id.node,
-                self_type,
                 env_pointer_alloca,
                 i,
                 captured_by_ref,
index a8256176c2658a737ff6b0e21e3aec6fcee14ed1..77412b00299ba672ef2a38676498d68e09ca521f 100644 (file)
@@ -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 {
index 532ef6908186640fda81e2cbebaeaa81946f2f09..23a261842b2d57443889fbf4a787674c8fb277b7 100644 (file)
@@ -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 @@ fn shallow_copy_raw<'blk>(&self,
     /// 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, &param_env));
         self.shallow_copy_raw(bcx, dst)
     }
 
index 6c75086fec60bc68254c7a4fa17d020f269b7dd4..f6c4ba64576f76d656efae22d1a556861501fffb 100644 (file)
 #[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
@@ -882,7 +884,6 @@ pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) {
 /// Adds the created metadata nodes directly to the crate's IR.
 pub fn create_captured_var_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                                 node_id: ast::NodeId,
-                                                env_data_type: Ty<'tcx>,
                                                 env_pointer: ValueRef,
                                                 env_index: uint,
                                                 captured_by_ref: bool,
@@ -928,7 +929,10 @@ pub fn create_captured_var_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let variable_type = node_id_type(bcx, node_id);
     let scope_metadata = bcx.fcx.debug_context.get_ref(cx, span).fn_metadata;
 
-    let llvm_env_data_type = type_of::type_of(cx, env_data_type);
+    // env_pointer is the alloca containing the pointer to the environment,
+    // so it's type is **EnvironmentType. In order to find out the type of
+    // the environment we have to "dereference" two times.
+    let llvm_env_data_type = val_ty(env_pointer).element_type().element_type();
     let byte_offset_of_var_in_env = machine::llelement_offset(cx,
                                                               llvm_env_data_type,
                                                               env_index);
@@ -2323,6 +2327,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 +3054,8 @@ enum DebugLocation {
     UnknownLocation
 }
 
+impl Copy for DebugLocation {}
+
 impl DebugLocation {
     fn new(scope: DIScope, line: uint, col: uint) -> DebugLocation {
         KnownLocation {
index d130dc0a55b1c0a4b111f92c5cf6e46b92a19ad6..e3e6fff723410ad29d4caacd8028aacaa59b2b01 100644 (file)
@@ -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,
index c00c477f4b8d2d3e5df4c31e47ac6aab2cd62c17..9234dfc48bd66dee344d6f4c5c8ff38278103bc1 100644 (file)
@@ -59,6 +59,8 @@ pub struct ModuleTranslation {
     pub llmod: ModuleRef,
 }
 
+impl Copy for ModuleTranslation {}
+
 pub struct CrateTranslation {
     pub modules: Vec<ModuleTranslation>,
     pub metadata_module: ModuleTranslation,
index 00f938191f8d9438276b766fa951432cc59b2a60..18ea8055a4eb5367d2b719ecf78387d20cd92f08 100644 (file)
@@ -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, _| {
index 8bff7602ddcead23ee8db815f8d61ec9db24b999..387af7390b209ec844917ee29f8f389d618bfd57 100644 (file)
@@ -31,6 +31,8 @@ pub struct Type {
     rf: TypeRef
 }
 
+impl Copy for Type {}
+
 macro_rules! ty (
     ($e:expr) => ( Type::from_ref(unsafe { $e }))
 )
index 005f6ca4c7086bc92cbf9abc26df53a51a2382e1..adc919c91bf36b8556b627d0ff71a81e47c6f809 100644 (file)
@@ -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",
index 33ea239412af664401d44c47031aedfc0bf9a804..fa06e039023e1b7596e708689ba2bca231d06ba2 100644 (file)
@@ -16,6 +16,8 @@
 
 pub struct Value(pub ValueRef);
 
+impl Copy for Value {}
+
 macro_rules! opt_val ( ($e:expr) => (
     unsafe {
         match $e {
@@ -123,9 +125,14 @@ pub fn is_a_terminator_inst(self) -> bool {
     }
 }
 
+/// 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 @@ pub fn get_next_use(self) -> Option<Use> {
 }
 
 /// Iterator for the users of a value
+#[allow(missing_copy_implementations)]
 pub struct Users {
     next: Option<Use>
 }
index d95ad9a11c87f1eff809aa7ca44fe778d0ecba50..7f1aad8ca77c56f81fb7dae5d1e2113e1b7239e7 100644 (file)
@@ -386,20 +386,81 @@ fn convert_angle_bracketed_parameters<'tcx, AC, RS>(this: &AC,
     (regions, types)
 }
 
+/// Returns the appropriate lifetime to use for any output lifetimes
+/// (if one exists) and a vector of the (pattern, number of lifetimes)
+/// corresponding to each input type/pattern.
+fn find_implied_output_region(input_tys: &[Ty], input_pats: Vec<String>)
+                              -> (Option<ty::Region>, Vec<(String, uint)>)
+{
+    let mut lifetimes_for_params: Vec<(String, uint)> = Vec::new();
+    let mut possible_implied_output_region = None;
+
+    for (input_type, input_pat) in input_tys.iter().zip(input_pats.into_iter()) {
+        let mut accumulator = Vec::new();
+        ty::accumulate_lifetimes_in_type(&mut accumulator, *input_type);
+
+        if accumulator.len() == 1 {
+            // there's a chance that the unique lifetime of this
+            // iteration will be the appropriate lifetime for output
+            // parameters, so lets store it.
+            possible_implied_output_region = Some(accumulator[0])
+        }
+
+        lifetimes_for_params.push((input_pat, accumulator.len()));
+    }
+
+    let implied_output_region = if lifetimes_for_params.iter().map(|&(_, n)| n).sum() == 1 {
+        assert!(possible_implied_output_region.is_some());
+        possible_implied_output_region
+    } else {
+        None
+    };
+    (implied_output_region, lifetimes_for_params)
+}
+
+fn convert_ty_with_lifetime_elision<'tcx,AC>(this: &AC,
+                                             implied_output_region: Option<ty::Region>,
+                                             param_lifetimes: Vec<(String, uint)>,
+                                             ty: &ast::Ty)
+                                             -> Ty<'tcx>
+    where AC: AstConv<'tcx>
+{
+    match implied_output_region {
+        Some(implied_output_region) => {
+            let rb = SpecificRscope::new(implied_output_region);
+            ast_ty_to_ty(this, &rb, ty)
+        }
+        None => {
+            // All regions must be explicitly specified in the output
+            // if the lifetime elision rules do not apply. This saves
+            // the user from potentially-confusing errors.
+            let rb = UnelidableRscope::new(param_lifetimes);
+            ast_ty_to_ty(this, &rb, ty)
+        }
+    }
+}
+
 fn convert_parenthesized_parameters<'tcx,AC>(this: &AC,
                                              data: &ast::ParenthesizedParameterData)
                                              -> Vec<Ty<'tcx>>
     where AC: AstConv<'tcx>
 {
     let binding_rscope = BindingRscope::new();
-
     let inputs = data.inputs.iter()
                             .map(|a_t| ast_ty_to_ty(this, &binding_rscope, &**a_t))
-                            .collect();
+                            .collect::<Vec<Ty<'tcx>>>();
+
+    let input_params = Vec::from_elem(inputs.len(), String::new());
+    let (implied_output_region,
+         params_lifetimes) = find_implied_output_region(&*inputs, input_params);
+
     let input_ty = ty::mk_tup(this.tcx(), inputs);
 
     let output = match data.output {
-        Some(ref output_ty) => ast_ty_to_ty(this, &binding_rscope, &**output_ty),
+        Some(ref output_ty) => convert_ty_with_lifetime_elision(this,
+                                                                implied_output_region,
+                                                                params_lifetimes,
+                                                                &**output_ty),
         None => ty::mk_nil(this.tcx()),
     };
 
@@ -1059,55 +1120,33 @@ fn ty_of_method_or_bare_fn<'a, 'tcx, AC: AstConv<'tcx>>(
     let self_and_input_tys: Vec<Ty> =
         self_ty.into_iter().chain(input_tys).collect();
 
-    let mut lifetimes_for_params: Vec<(String, Vec<ty::Region>)> = Vec::new();
 
     // Second, if there was exactly one lifetime (either a substitution or a
     // reference) in the arguments, then any anonymous regions in the output
     // have that lifetime.
-    if implied_output_region.is_none() {
-        let mut self_and_input_tys_iter = self_and_input_tys.iter();
-        if self_ty.is_some() {
+    let lifetimes_for_params = if implied_output_region.is_none() {
+        let input_tys = if self_ty.is_some() {
             // Skip the first argument if `self` is present.
-            drop(self_and_input_tys_iter.next())
-        }
-
-        for (input_type, input_pat) in self_and_input_tys_iter.zip(input_pats.into_iter()) {
-            let mut accumulator = Vec::new();
-            ty::accumulate_lifetimes_in_type(&mut accumulator, *input_type);
-            lifetimes_for_params.push((input_pat, accumulator));
-        }
-
-        if lifetimes_for_params.iter().map(|&(_, ref x)| x.len()).sum() == 1 {
-            implied_output_region =
-                Some(lifetimes_for_params.iter()
-                                         .filter_map(|&(_, ref x)|
-                                            if x.len() == 1 { Some(x[0]) } else { None })
-                                         .next().unwrap());
-        }
-    }
+            self_and_input_tys.slice_from(1)
+        } else {
+            self_and_input_tys.slice_from(0)
+        };
 
-    let param_lifetimes: Vec<(String, uint)> = lifetimes_for_params.into_iter()
-                                                                   .map(|(n, v)| (n, v.len()))
-                                                                   .filter(|&(_, l)| l != 0)
-                                                                   .collect();
+        let (ior, lfp) = find_implied_output_region(input_tys, input_pats);
+        implied_output_region = ior;
+        lfp
+    } else {
+        vec![]
+    };
 
     let output_ty = match decl.output {
         ast::Return(ref output) if output.node == ast::TyInfer =>
             ty::FnConverging(this.ty_infer(output.span)),
         ast::Return(ref output) =>
-            ty::FnConverging(match implied_output_region {
-                Some(implied_output_region) => {
-                    let rb = SpecificRscope::new(implied_output_region);
-                    ast_ty_to_ty(this, &rb, &**output)
-                }
-                None => {
-                    // All regions must be explicitly specified in the output
-                    // if the lifetime elision rules do not apply. This saves
-                    // the user from potentially-confusing errors.
-                    let rb = UnelidableRscope::new(param_lifetimes);
-                    ast_ty_to_ty(this, &rb, &**output)
-                }
-            }),
+            ty::FnConverging(convert_ty_with_lifetime_elision(this,
+                                                              implied_output_region,
+                                                              lifetimes_for_params,
+                                                              &**output)),
         ast::NoReturn(_) => ty::FnDiverging
     };
 
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
new file mode 100644 (file)
index 0000000..ee93c89
--- /dev/null
@@ -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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use syntax::ast;
+use syntax::codemap::Span;
+use CrateCtxt;
+
+/// Check that it is legal to call methods of the trait corresponding
+/// to `trait_id` (this only cares about the trait, not the specific
+/// method that is called)
+pub fn check_legal_trait_for_method_call(ccx: &CrateCtxt, span: Span, trait_id: ast::DefId) {
+    let tcx = ccx.tcx;
+    let did = Some(trait_id);
+    let li = &tcx.lang_items;
+
+    if did == li.drop_trait() {
+        span_err!(tcx.sess, span, E0040, "explicit use of destructor method");
+    } else if !tcx.sess.features.borrow().unboxed_closures {
+        // the #[feature(unboxed_closures)] feature isn't
+        // activated so we need to enforce the closure
+        // restrictions.
+
+        let method = if did == li.fn_trait() {
+            "call"
+        } else if did == li.fn_mut_trait() {
+            "call_mut"
+        } else if did == li.fn_once_trait() {
+            "call_once"
+        } else {
+            return // not a closure method, everything is OK.
+        };
+
+        span_err!(tcx.sess, span, E0174,
+                  "explicit use of unboxed closure method `{}` is experimental",
+                  method);
+        span_help!(tcx.sess, span,
+                   "add `#![feature(unboxed_closures)]` to the crate attributes to enable");
+    }
+}
index 1fe73f0478d566a111a8f93f9ef4200e55954423..b6a9e2cbc59eae956c6874d780a4832ea65c9022 100644 (file)
@@ -10,7 +10,7 @@
 
 use super::probe;
 
-use check::{mod, FnCtxt, NoPreference, PreferMutLvalue};
+use check::{mod, FnCtxt, NoPreference, PreferMutLvalue, callee};
 use middle::subst::{mod, Subst};
 use middle::traits;
 use middle::ty::{mod, Ty};
@@ -90,7 +90,7 @@ fn confirm(&mut self,
         let self_ty = self.adjust_self_ty(unadjusted_self_ty, &pick.adjustment);
 
         // Make sure nobody calls `drop()` explicitly.
-        self.enforce_drop_trait_limitations(&pick);
+        self.enforce_illegal_method_limitations(&pick);
 
         // Create substitutions for the method's type parameters.
         let (rcvr_substs, method_origin) =
@@ -624,14 +624,11 @@ fn infcx(&self) -> &'a InferCtxt<'a, 'tcx> {
         self.fcx.infcx()
     }
 
-    fn enforce_drop_trait_limitations(&self, pick: &probe::Pick) {
+    fn enforce_illegal_method_limitations(&self, pick: &probe::Pick) {
         // Disallow calls to the method `drop` defined in the `Drop` trait.
         match pick.method_ty.container {
             ty::TraitContainer(trait_def_id) => {
-                if Some(trait_def_id) == self.tcx().lang_items.drop_trait() {
-                    span_err!(self.tcx().sess, self.span, E0040,
-                              "explicit call to destructor");
-                }
+                callee::check_legal_trait_for_method_call(self.fcx.ccx, self.span, trait_def_id)
             }
             ty::ImplContainer(..) => {
                 // Since `drop` is a trait method, we expect that any
index f87a4c9294bab60369b6c4522556083039cacff2..b6c9d8b2d2176fcb8438706b201ad0b3bd0e66b1 100644 (file)
@@ -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.
index cdf34c7f4d2f3c8dc845d84053407341581d2bbb..8288cce395838f8a07de8b07418a9bb7b6c98547 100644 (file)
 pub mod method;
 pub mod wf;
 mod closure;
+mod callee;
 
 /// Fields that are part of a `FnCtxt` which are inherited by
 /// closures defined within the function.  For example:
@@ -209,6 +210,8 @@ enum Expectation<'tcx> {
     ExpectCastableToType(Ty<'tcx>),
 }
 
+impl<'tcx> Copy for Expectation<'tcx> {}
+
 #[deriving(Clone)]
 pub struct FnStyleState {
     pub def: ast::NodeId,
@@ -216,6 +219,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 }
@@ -406,7 +411,7 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                decl, id, body, &inh);
 
             vtable::select_all_fcx_obligations_or_error(&fcx);
-            regionck::regionck_fn(&fcx, id, body);
+            regionck::regionck_fn(&fcx, id, decl, body);
             fcx.default_diverging_type_variables_to_nil();
             writeback::resolve_type_vars_in_fn(&fcx, decl, body);
         }
@@ -2117,6 +2122,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 +3000,8 @@ pub enum DerefArgs {
     DoDerefArgs
 }
 
+impl Copy for DerefArgs {}
+
 /// Controls whether the arguments are tupled. This is used for the call
 /// operator.
 ///
@@ -5087,8 +5096,17 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         }
 
         // Case 3. Reference to a method.
-        def::DefStaticMethod(..) => {
+        def::DefStaticMethod(_, providence) |
+        def::DefMethod(_, _, providence) => {
             assert!(path.segments.len() >= 2);
+
+            match providence {
+                def::FromTrait(trait_did) => {
+                    callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
+                }
+                def::FromImpl(_) => {}
+            }
+
             segment_spaces = Vec::from_elem(path.segments.len() - 2, None);
             segment_spaces.push(Some(subst::TypeSpace));
             segment_spaces.push(Some(subst::FnSpace));
@@ -5100,7 +5118,6 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         def::DefMod(..) |
         def::DefForeignMod(..) |
         def::DefLocal(..) |
-        def::DefMethod(..) |
         def::DefUse(..) |
         def::DefRegion(..) |
         def::DefLabel(..) |
index 2aec4393de9426e1361240a25aaf21c12618d642..80ee2cce4ce709e954df33a1c15ae33367e01e6c 100644 (file)
@@ -158,11 +158,11 @@ pub fn regionck_item(fcx: &FnCtxt, item: &ast::Item) {
     fcx.infcx().resolve_regions_and_report_errors();
 }
 
-pub fn regionck_fn(fcx: &FnCtxt, id: ast::NodeId, blk: &ast::Block) {
+pub fn regionck_fn(fcx: &FnCtxt, id: ast::NodeId, decl: &ast::FnDecl, blk: &ast::Block) {
     let mut rcx = Rcx::new(fcx, blk.id);
     if fcx.err_count_since_creation() == 0 {
         // regionck assumes typeck succeeded
-        rcx.visit_fn_body(id, blk);
+        rcx.visit_fn_body(id, decl, blk);
     }
 
     // Region checking a fn can introduce new trait obligations,
@@ -328,6 +328,7 @@ pub fn resolve_expr_type_adjusted(&mut self, expr: &ast::Expr) -> Ty<'tcx> {
 
     fn visit_fn_body(&mut self,
                      id: ast::NodeId,
+                     fn_decl: &ast::FnDecl,
                      body: &ast::Block)
     {
         // When we enter a function, we can derive
@@ -343,6 +344,7 @@ fn visit_fn_body(&mut self,
 
         let len = self.region_param_pairs.len();
         self.relate_free_regions(fn_sig.as_slice(), body.id);
+        link_fn_args(self, CodeExtent::from_node_id(body.id), fn_decl.inputs.as_slice());
         self.visit_block(body);
         self.visit_region_obligations(body.id);
         self.region_param_pairs.truncate(len);
@@ -480,9 +482,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Rcx<'a, 'tcx> {
     // hierarchy, and in particular the relationships between free
     // regions, until regionck, as described in #3238.
 
-    fn visit_fn(&mut self, _fk: visit::FnKind<'v>, _fd: &'v ast::FnDecl,
+    fn visit_fn(&mut self, _fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
                 b: &'v ast::Block, _s: Span, id: ast::NodeId) {
-        self.visit_fn_body(id, b)
+        self.visit_fn_body(id, fd, b)
     }
 
     fn visit_item(&mut self, i: &ast::Item) { visit_item(self, i); }
@@ -1288,7 +1290,6 @@ fn link_local(rcx: &Rcx, local: &ast::Local) {
 /// then ensures that the lifetime of the resulting pointer is
 /// linked to the lifetime of its guarantor (if any).
 fn link_match(rcx: &Rcx, discr: &ast::Expr, arms: &[ast::Arm]) {
-
     debug!("regionck::for_match()");
     let mc = mc::MemCategorizationContext::new(rcx);
     let discr_cmt = ignore_err!(mc.cat_expr(discr));
@@ -1300,12 +1301,32 @@ fn link_match(rcx: &Rcx, discr: &ast::Expr, arms: &[ast::Arm]) {
     }
 }
 
+/// Computes the guarantors for any ref bindings in a match and
+/// then ensures that the lifetime of the resulting pointer is
+/// linked to the lifetime of its guarantor (if any).
+fn link_fn_args(rcx: &Rcx, body_scope: CodeExtent, args: &[ast::Arg]) {
+    debug!("regionck::link_fn_args(body_scope={})", body_scope);
+    let mc = mc::MemCategorizationContext::new(rcx);
+    for arg in args.iter() {
+        let arg_ty = rcx.fcx.node_ty(arg.id);
+        let re_scope = ty::ReScope(body_scope);
+        let arg_cmt = mc.cat_rvalue(arg.id, arg.ty.span, re_scope, arg_ty);
+        debug!("arg_ty={} arg_cmt={}",
+               arg_ty.repr(rcx.tcx()),
+               arg_cmt.repr(rcx.tcx()));
+        link_pattern(rcx, mc, arg_cmt, &*arg.pat);
+    }
+}
+
 /// Link lifetimes of any ref bindings in `root_pat` to the pointers found in the discriminant, if
 /// needed.
 fn link_pattern<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
                           mc: mc::MemCategorizationContext<Rcx<'a, 'tcx>>,
                           discr_cmt: mc::cmt<'tcx>,
                           root_pat: &ast::Pat) {
+    debug!("link_pattern(discr_cmt={}, root_pat={})",
+           discr_cmt.repr(rcx.tcx()),
+           root_pat.repr(rcx.tcx()));
     let _ = mc.cat_pattern(discr_cmt, root_pat, |mc, sub_cmt, sub_pat| {
             match sub_pat.node {
                 // `ref x` pattern
index b9f7eb3f271b7b2bcc4aa28ad82938218b95c3ff..80363055a4bf0ea6206dc7bde15a49063dbc9bdb 100644 (file)
@@ -366,6 +366,15 @@ pub fn report_selection_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                     "overflow evaluating the trait `{}` for the type `{}`",
                     trait_ref.user_string(fcx.tcx()),
                     self_ty.user_string(fcx.tcx())).as_slice());
+
+            let current_limit = fcx.tcx().sess.recursion_limit.get();
+            let suggested_limit = current_limit * 2;
+            fcx.tcx().sess.span_note(
+                obligation.cause.span,
+                format!(
+                    "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate",
+                    suggested_limit)[]);
+
             note_obligation_cause(fcx, obligation);
         }
         Unimplemented => {
index 1769c588ec1de51244bafa77bf7b32fe8ee31b00..a011982a1fc53b2613e412ed1c2636e5c66909aa 100644 (file)
@@ -203,6 +203,11 @@ fn check_impl(&mut self,
                 }
             }
 
+            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
index 777f354bec126520b4724a095005a6dcc09eeb02..48f1ef8da1d54672cc6fb4b1264f6d1aab3cbc82 100644 (file)
@@ -354,6 +354,8 @@ enum ResolveReason {
     ResolvingUnboxedClosure(ast::DefId),
 }
 
+impl Copy for ResolveReason {}
+
 impl ResolveReason {
     fn span(&self, tcx: &ty::ctxt) -> Span {
         match *self {
index b8642ddde4082448f69471b6cfc39b1fc46a2da6..c4e1f6fe8eb180cfc5a7be8db2383d0da13778ce 100644 (file)
 
 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 @@ fn check(&self, krate: &Crate) {
         // 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,
@@ -211,6 +212,9 @@ fn check_implementation(&self,
                    trait_ref.repr(self.crate_context.tcx),
                    token::get_ident(item.ident));
 
+            enforce_trait_manually_implementable(self.crate_context.tcx,
+                                                 item.span,
+                                                 trait_ref.def_id);
             self.add_trait_impl(trait_ref.def_id, impl_did);
         }
 
@@ -474,6 +478,93 @@ fn populate_destructor_table(&self) {
             }
         }
     }
+
+    /// 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(&copy_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, &param_env.free_substs);
+
+            match ty::can_type_implement_copy(tcx, self_type, &param_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 enforce_trait_manually_implementable(tcx: &ty::ctxt, sp: Span, trait_def_id: ast::DefId) {
+    if tcx.sess.features.borrow().unboxed_closures {
+        // the feature gate allows all of them
+        return
+    }
+    let did = Some(trait_def_id);
+    let li = &tcx.lang_items;
+
+    let trait_name = if did == li.fn_trait() {
+        "Fn"
+    } else if did == li.fn_mut_trait() {
+        "FnMut"
+    } else if did == li.fn_once_trait() {
+        "FnOnce"
+    } else {
+        return // everything OK
+    };
+    span_err!(tcx.sess, sp, E0173, "manual implementations of `{}` are experimental", trait_name);
+    span_help!(tcx.sess, sp,
+               "add `#![feature(unboxed_closures)]` to the crate attributes to enable");
 }
 
 fn subst_receiver_types_in_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
index 717e886029a3d1bf7eb5a1e828c2f27a151243c6..74ac9c480defecc280fecc9305903a370895a168 100644 (file)
@@ -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,
index 36e81f18103b873dfd1f1ae61d25cd725b96de18..e026fbd05c7f039c5ca6e4fc9c83d4f7a07744de 100644 (file)
@@ -53,7 +53,7 @@
     E0035,
     E0036,
     E0038,
-    E0040,
+    E0040, // explicit use of destructor method
     E0044,
     E0045,
     E0046,
     E0168,
     E0169,
     E0171,
-    E0172
+    E0172,
+    E0173, // manual implementations of unboxed closure traits are experimental
+    E0174 // explicit use of unboxed closure methods are experimental
 )
index 3bca24f479f704d487eae5cab9944d8dd2bd609e..39c7a87837ca100359af572691b0bcc518a9f61e 100644 (file)
@@ -38,6 +38,8 @@ fn anon_regions(&self,
 // 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<ty::Region> {
         None
@@ -77,6 +79,7 @@ fn anon_regions(&self,
 // 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
 }
index ade3144ce414e8485f44a84d42179d2094aa280e..56f974ad665c6a27cfef5a721ebb136c938e5589 100644 (file)
@@ -232,12 +232,16 @@ pub fn infer_variance(tcx: &ty::ctxt) {
 #[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 @@ fn write(&self) {
 
             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);
index bc870d39c5d7ff924440fc546e6497e296e84b8c..df7b922bd1abc31a4884633a13d4e6c433affb4a 100644 (file)
@@ -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<PrimitiveType> {
         match s.as_slice() {
@@ -1843,6 +1847,8 @@ pub enum Mutability {
     Immutable,
 }
 
+impl Copy for Mutability {}
+
 impl Clean<Mutability> for ast::Mutability {
     fn clean(&self, _: &DocContext) -> Mutability {
         match self {
index adfd9aa821328868e7fc0419ba0f70407f676418..1aac91c4a5c7ac96b8a71a6c0ad29432260ba7f4 100644 (file)
@@ -82,6 +82,8 @@ pub enum StructType {
     Unit
 }
 
+impl Copy for StructType {}
+
 pub enum TypeBound {
     RegionBound,
     TraitBound(ast::TraitRef)
index 0fca59962d40c3ecd5667f9f997fce9558c51407..68ff2ddbcb0e194440e174e5a2c8adff4fec142b 100644 (file)
 /// 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<ast::Visibility> {
         let VisSpace(v) = *self; v
index 0ad12b957ba8f868793ae5261a5078035325ce2f..86787e5c805484c6f8c3ca91104e3dc31d47126f 100644 (file)
@@ -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 {
index dab25c3b2ee59e2fc3d534e3845ddf00bdd2031a..296493f3ba30012d052b8b2097016056ff1a4b3f 100644 (file)
@@ -225,7 +225,13 @@ struct SourceCollector<'a> {
 // 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
index 42f4c2a0ca63a19dacd2c03c3eac921e893a31c6..881270afe140c304a14c1108b6e2e5712328939b 100644 (file)
@@ -39,6 +39,8 @@ pub struct Counts {
     pub unmarked: uint,
 }
 
+impl Copy for Counts {}
+
 impl Add<Counts, Counts> for Counts {
     fn add(&self, other: &Counts) -> Counts {
         Counts {
index 714bbd569bdbc7c279aaf6483d9df91fe84ce425..e918a496d55316d3e5ada32472b58c2aed098139 100644 (file)
@@ -26,6 +26,7 @@
 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 {
index 261bd1b9f8cb88367ad0b1d30180322dbccf044e..07094f08c5de9684bf7986b5d76d803f72ddbaea 100644 (file)
@@ -85,6 +85,7 @@
 ///
 /// 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,
index 2f0daf8f6e2429a073bc7d4d1c7794e5a1a2ea39..5b58ec8fd3a8bb4e834cdeff52cdfebc27bca8e5 100644 (file)
@@ -361,6 +361,7 @@ mod os {
 
     #[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 @@ pub struct pthread_mutex_t {
             __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 @@ pub struct pthread_cond_t {
 
     #[cfg(target_os = "linux")]
     mod os {
+        use core::kinds::Copy;
         use libc;
 
         // minus 8 because we have an 'align' field
@@ -431,12 +438,17 @@ pub struct pthread_mutex_t {
             __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],
index 697ee95df4c0f0f757820f4287093eecd2bd3a8b..5bc542a84e6e8bb9640b0c8f1dc0dd69593a8da7 100644 (file)
@@ -77,6 +77,7 @@
 
 use libunwind as uw;
 
+#[allow(missing_copy_implementations)]
 pub struct Unwinder {
     unwinding: bool,
 }
@@ -399,14 +400,18 @@ pub extern "C" fn rust_eh_personality_catch(
 #[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)]
@@ -417,6 +422,8 @@ pub enum EXCEPTION_DISPOSITION {
         ExceptionCollidedUnwind
     }
 
+    impl Copy for EXCEPTION_DISPOSITION {}
+
     type _Unwind_Personality_Fn =
         extern "C" fn(
             version: c_int,
index c77fbd4aee06752c7eed9df49623c6f425b0dd3d..fd30c3a48d2d5e8870703617990c745179f51984 100644 (file)
@@ -29,6 +29,9 @@
 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);
index c8ec1700a1dae94df2d769430b3bbf1e8bf1026d..59faf75c0c30cffccb66c2828135d539fee4e506 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -26,27 +26,43 @@ pub enum CharacterSet {
     UrlSafe
 }
 
+impl Copy for CharacterSet {}
+
+/// Available newline types
+pub enum Newline {
+    /// A linefeed (i.e. Unix-style newline)
+    LF,
+    /// A carriage return and a linefeed (i.e. Windows-style newline)
+    CRLF
+}
+
+impl Copy for Newline {}
+
 /// Contains configuration parameters for `to_base64`.
 pub struct Config {
     /// Character set to use
     pub char_set: CharacterSet,
+    /// Newline to use
+    pub newline: Newline,
     /// True to pad output with `=` characters
     pub pad: bool,
     /// `Some(len)` to wrap lines at `len`, `None` to disable line wrapping
     pub line_length: Option<uint>
 }
 
+impl Copy for Config {}
+
 /// Configuration for RFC 4648 standard base64 encoding
 pub static STANDARD: Config =
-    Config {char_set: Standard, pad: true, line_length: None};
+    Config {char_set: Standard, newline: Newline::CRLF, pad: true, line_length: None};
 
 /// Configuration for RFC 4648 base64url encoding
 pub static URL_SAFE: Config =
-    Config {char_set: UrlSafe, pad: false, line_length: None};
+    Config {char_set: UrlSafe, newline: Newline::CRLF, pad: false, line_length: None};
 
 /// Configuration for RFC 2045 MIME base64 encoding
 pub static MIME: Config =
-    Config {char_set: Standard, pad: true, line_length: Some(76)};
+    Config {char_set: Standard, newline: Newline::CRLF, pad: true, line_length: Some(76)};
 
 static STANDARD_CHARS: &'static[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
                                         abcdefghijklmnopqrstuvwxyz\
@@ -83,24 +99,30 @@ fn to_base64(&self, config: Config) -> String {
             UrlSafe => URLSAFE_CHARS
         };
 
-        let mut v = Vec::new();
+        // In general, this Vec only needs (4/3) * self.len() memory, but
+        // addition is faster than multiplication and division.
+        let mut v = Vec::with_capacity(self.len() + self.len());
         let mut i = 0;
         let mut cur_length = 0;
         let len = self.len();
-        while i < len - (len % 3) {
-            match config.line_length {
-                Some(line_length) =>
-                    if cur_length >= line_length {
-                        v.push(b'\r');
-                        v.push(b'\n');
-                        cur_length = 0;
-                    },
-                None => ()
+        let mod_len = len % 3;
+        let cond_len = len - mod_len;
+        let newline = match config.newline {
+            Newline::LF => b"\n",
+            Newline::CRLF => b"\r\n"
+        };
+        while i < cond_len {
+            let (first, second, third) = (self[i], self[i + 1], self[i + 2]);
+            if let Some(line_length) = config.line_length {
+                if cur_length >= line_length {
+                    v.push_all(newline);
+                    cur_length = 0;
+                }
             }
 
-            let n = (self[i] as u32) << 16 |
-                    (self[i + 1] as u32) << 8 |
-                    (self[i + 2] as u32);
+            let n = (first  as u32) << 16 |
+                    (second as u32) << 8 |
+                    (third  as u32);
 
             // This 24-bit number gets separated into four 6-bit numbers.
             v.push(bytes[((n >> 18) & 63) as uint]);
@@ -112,20 +134,17 @@ fn to_base64(&self, config: Config) -> String {
             i += 3;
         }
 
-        if len % 3 != 0 {
-            match config.line_length {
-                Some(line_length) =>
-                    if cur_length >= line_length {
-                        v.push(b'\r');
-                        v.push(b'\n');
-                    },
-                None => ()
+        if mod_len != 0 {
+            if let Some(line_length) = config.line_length {
+                if cur_length >= line_length {
+                    v.push_all(newline);
+                }
             }
         }
 
         // Heh, would be cool if we knew this was exhaustive
         // (the dream of bounded integer types)
-        match len % 3 {
+        match mod_len {
             0 => (),
             1 => {
                 let n = (self[i] as u32) << 16;
@@ -168,6 +187,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 {
@@ -226,7 +247,7 @@ fn from_base64(&self) -> Result<Vec<u8>, FromBase64Error> {
 
 impl FromBase64 for [u8] {
     fn from_base64(&self) -> Result<Vec<u8>, FromBase64Error> {
-        let mut r = Vec::new();
+        let mut r = Vec::with_capacity(self.len());
         let mut buf: u32 = 0;
         let mut modulus = 0i;
 
@@ -282,7 +303,7 @@ fn from_base64(&self) -> Result<Vec<u8>, FromBase64Error> {
 mod tests {
     extern crate test;
     use self::test::Bencher;
-    use base64::{Config, FromBase64, ToBase64, STANDARD, URL_SAFE};
+    use base64::{Config, Newline, FromBase64, ToBase64, STANDARD, URL_SAFE};
 
     #[test]
     fn test_to_base64_basic() {
@@ -296,14 +317,27 @@ fn test_to_base64_basic() {
     }
 
     #[test]
-    fn test_to_base64_line_break() {
+    fn test_to_base64_crlf_line_break() {
         assert!(![0u8, ..1000].to_base64(Config {line_length: None, ..STANDARD})
                               .contains("\r\n"));
-        assert_eq!("foobar".as_bytes().to_base64(Config {line_length: Some(4),
-                                                         ..STANDARD}),
+        assert_eq!(b"foobar".to_base64(Config {line_length: Some(4),
+                                               ..STANDARD}),
                    "Zm9v\r\nYmFy");
     }
 
+    #[test]
+    fn test_to_base64_lf_line_break() {
+        assert!(![0u8, ..1000].to_base64(Config {line_length: None,
+                                                 newline: Newline::LF,
+                                                 ..STANDARD})
+                              .as_slice()
+                              .contains("\n"));
+        assert_eq!(b"foobar".to_base64(Config {line_length: Some(4),
+                                               newline: Newline::LF,
+                                               ..STANDARD}),
+                   "Zm9v\nYmFy");
+    }
+
     #[test]
     fn test_to_base64_padding() {
         assert_eq!("f".as_bytes().to_base64(Config {pad: false, ..STANDARD}), "Zg");
@@ -338,6 +372,10 @@ fn test_from_base64_newlines() {
                    b"foobar");
         assert_eq!("Zm9vYg==\r\n".from_base64().unwrap(),
                    b"foob");
+        assert_eq!("Zm9v\nYmFy".from_base64().unwrap(),
+                   b"foobar");
+        assert_eq!("Zm9vYg==\n".from_base64().unwrap(),
+                   b"foob");
     }
 
     #[test]
index 4c20f72cac5b1a4119367553e1fac8ab57286662..22392056ddf21d29fdd7d691b587328abb67afee 100644 (file)
@@ -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 {
index 248d78236ad4b0d9c600e3fc48c4a8fd4caf4291..d28bd1b9df040bd912fc3c84739d549b9e8d060c 100644 (file)
@@ -91,7 +91,7 @@
 //! fn main() {
 //!     let object = TestStruct {
 //!         data_int: 1,
-//!         data_str: "toto".to_string(),
+//!         data_str: "homura".to_string(),
 //!         data_vector: vec![2,3,4,5],
 //!     };
 //!
 //!     // Serialize using `ToJson`
 //!     let input_data = TestStruct {
 //!         data_int: 1,
-//!         data_str: "toto".to_string(),
+//!         data_str: "madoka".to_string(),
 //!         data_vector: vec![2,3,4,5],
 //!     };
 //!     let json_obj: Json = input_data.to_json();
@@ -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;
 
@@ -386,7 +390,8 @@ fn spaces(wr: &mut io::Writer, mut n: uint) -> Result<(), io::IoError> {
 fn fmt_number_or_null(v: f64) -> string::String {
     match v.classify() {
         FPNaN | FPInfinite => string::String::from_str("null"),
-        _ => f64::to_str_digits(v, 6u)
+        _ if v.fract() != 0f64 => f64::to_str_digits(v, 6u),
+        _ => f64::to_str_digits(v, 6u) + ".0",
     }
 }
 
@@ -419,17 +424,17 @@ pub fn buffer_encode<T:Encodable<Encoder<'a>, io::IoError>>(object: &T) -> Vec<u
 impl<'a> ::Encoder<io::IoError> for Encoder<'a> {
     fn emit_nil(&mut self) -> EncodeResult { write!(self.writer, "null") }
 
-    fn emit_uint(&mut self, v: uint) -> EncodeResult { self.emit_f64(v as f64) }
-    fn emit_u64(&mut self, v: u64) -> EncodeResult { self.emit_f64(v as f64) }
-    fn emit_u32(&mut self, v: u32) -> EncodeResult { self.emit_f64(v as f64) }
-    fn emit_u16(&mut self, v: u16) -> EncodeResult { self.emit_f64(v as f64) }
-    fn emit_u8(&mut self, v: u8) -> EncodeResult  { self.emit_f64(v as f64) }
+    fn emit_uint(&mut self, v: uint) -> EncodeResult { write!(self.writer, "{}", v) }
+    fn emit_u64(&mut self, v: u64) -> EncodeResult { write!(self.writer, "{}", v) }
+    fn emit_u32(&mut self, v: u32) -> EncodeResult { write!(self.writer, "{}", v) }
+    fn emit_u16(&mut self, v: u16) -> EncodeResult { write!(self.writer, "{}", v) }
+    fn emit_u8(&mut self, v: u8) -> EncodeResult { write!(self.writer, "{}", v) }
 
-    fn emit_int(&mut self, v: int) -> EncodeResult { self.emit_f64(v as f64) }
-    fn emit_i64(&mut self, v: i64) -> EncodeResult { self.emit_f64(v as f64) }
-    fn emit_i32(&mut self, v: i32) -> EncodeResult { self.emit_f64(v as f64) }
-    fn emit_i16(&mut self, v: i16) -> EncodeResult { self.emit_f64(v as f64) }
-    fn emit_i8(&mut self, v: i8) -> EncodeResult  { self.emit_f64(v as f64) }
+    fn emit_int(&mut self, v: int) -> EncodeResult { write!(self.writer, "{}", v) }
+    fn emit_i64(&mut self, v: i64) -> EncodeResult { write!(self.writer, "{}", v) }
+    fn emit_i32(&mut self, v: i32) -> EncodeResult { write!(self.writer, "{}", v) }
+    fn emit_i16(&mut self, v: i16) -> EncodeResult { write!(self.writer, "{}", v) }
+    fn emit_i8(&mut self, v: i8) -> EncodeResult { write!(self.writer, "{}", v) }
 
     fn emit_bool(&mut self, v: bool) -> EncodeResult {
         if v {
@@ -442,7 +447,9 @@ fn emit_bool(&mut self, v: bool) -> EncodeResult {
     fn emit_f64(&mut self, v: f64) -> EncodeResult {
         write!(self.writer, "{}", fmt_number_or_null(v))
     }
-    fn emit_f32(&mut self, v: f32) -> EncodeResult { self.emit_f64(v as f64) }
+    fn emit_f32(&mut self, v: f32) -> EncodeResult {
+        self.emit_f64(v as f64)
+    }
 
     fn emit_char(&mut self, v: char) -> EncodeResult {
         escape_char(self.writer, v)
@@ -451,7 +458,9 @@ fn emit_str(&mut self, v: &str) -> EncodeResult {
         escape_str(self.writer, v)
     }
 
-    fn emit_enum(&mut self, _name: &str, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
+    fn emit_enum(&mut self,
+                 _name: &str,
+                 f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
         f(self)
     }
 
@@ -620,17 +629,17 @@ pub fn set_indent<'a>(&mut self, indent: uint) {
 impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
     fn emit_nil(&mut self) -> EncodeResult { write!(self.writer, "null") }
 
-    fn emit_uint(&mut self, v: uint) -> EncodeResult { self.emit_f64(v as f64) }
-    fn emit_u64(&mut self, v: u64) -> EncodeResult { self.emit_f64(v as f64) }
-    fn emit_u32(&mut self, v: u32) -> EncodeResult { self.emit_f64(v as f64) }
-    fn emit_u16(&mut self, v: u16) -> EncodeResult { self.emit_f64(v as f64) }
-    fn emit_u8(&mut self, v: u8) -> EncodeResult { self.emit_f64(v as f64) }
+    fn emit_uint(&mut self, v: uint) -> EncodeResult { write!(self.writer, "{}", v) }
+    fn emit_u64(&mut self, v: u64) -> EncodeResult { write!(self.writer, "{}", v) }
+    fn emit_u32(&mut self, v: u32) -> EncodeResult { write!(self.writer, "{}", v) }
+    fn emit_u16(&mut self, v: u16) -> EncodeResult { write!(self.writer, "{}", v) }
+    fn emit_u8(&mut self, v: u8) -> EncodeResult { write!(self.writer, "{}", v) }
 
-    fn emit_int(&mut self, v: int) -> EncodeResult { self.emit_f64(v as f64) }
-    fn emit_i64(&mut self, v: i64) -> EncodeResult { self.emit_f64(v as f64) }
-    fn emit_i32(&mut self, v: i32) -> EncodeResult { self.emit_f64(v as f64) }
-    fn emit_i16(&mut self, v: i16) -> EncodeResult { self.emit_f64(v as f64) }
-    fn emit_i8(&mut self, v: i8) -> EncodeResult { self.emit_f64(v as f64) }
+    fn emit_int(&mut self, v: int) -> EncodeResult { write!(self.writer, "{}", v) }
+    fn emit_i64(&mut self, v: i64) -> EncodeResult { write!(self.writer, "{}", v) }
+    fn emit_i32(&mut self, v: i32) -> EncodeResult { write!(self.writer, "{}", v) }
+    fn emit_i16(&mut self, v: i16) -> EncodeResult { write!(self.writer, "{}", v) }
+    fn emit_i8(&mut self, v: i8) -> EncodeResult { write!(self.writer, "{}", v) }
 
     fn emit_bool(&mut self, v: bool) -> EncodeResult {
         if v {
@@ -662,7 +671,7 @@ fn emit_enum(&mut self,
 
     fn emit_enum_variant(&mut self,
                          name: &str,
-                         _: uint,
+                         _id: uint,
                          cnt: uint,
                          f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
         if cnt == 0 {
@@ -1942,7 +1951,7 @@ macro_rules! expect(
     ($e:expr, Null) => ({
         match $e {
             Json::Null => Ok(()),
-            other => Err(ExpectedError("Null".to_string(),
+            other => Err(ExpectedError("Null".into_string(),
                                        format!("{}", other)))
         }
     });
@@ -1961,33 +1970,22 @@ macro_rules! read_primitive {
     ($name:ident, $ty:ty) => {
         fn $name(&mut self) -> DecodeResult<$ty> {
             match self.pop() {
-                Json::I64(f) => {
-                    match num::cast(f) {
-                        Some(f) => Ok(f),
-                        None => Err(ExpectedError("Number".to_string(), format!("{}", f))),
-                    }
-                }
-                Json::U64(f) => {
-                    match num::cast(f) {
-                        Some(f) => Ok(f),
-                        None => Err(ExpectedError("Number".to_string(), format!("{}", f))),
-                    }
-                }
-                Json::F64(f) => {
-                    match num::cast(f) {
-                        Some(f) => Ok(f),
-                        None => Err(ExpectedError("Number".to_string(), format!("{}", f))),
-                    }
-                }
-                Json::String(s) => {
-                    // re: #12967.. a type w/ numeric keys (ie HashMap<uint, V> etc)
-                    // is going to have a string here, as per JSON spec.
-                    match std::str::from_str(s.as_slice()) {
-                        Some(f) => Ok(f),
-                        None => Err(ExpectedError("Number".to_string(), s)),
-                    }
+                Json::I64(f) => match num::cast(f) {
+                    Some(f) => Ok(f),
+                    None => Err(ExpectedError("Number".into_string(), format!("{}", f))),
+                },
+                Json::U64(f) => match num::cast(f) {
+                    Some(f) => Ok(f),
+                    None => Err(ExpectedError("Number".into_string(), format!("{}", f))),
                 },
-                value => Err(ExpectedError("Number".to_string(), format!("{}", value)))
+                Json::F64(f) => Err(ExpectedError("Integer".into_string(), format!("{}", f))),
+                // re: #12967.. a type w/ numeric keys (ie HashMap<uint, V> etc)
+                // is going to have a string here, as per JSON spec.
+                Json::String(s) => match std::str::from_str(s.as_slice()) {
+                    Some(f) => Ok(f),
+                    None => Err(ExpectedError("Number".into_string(), s)),
+                },
+                value => Err(ExpectedError("Number".into_string(), format!("{}", value))),
             }
         }
     }
@@ -2023,11 +2021,11 @@ fn read_f64(&mut self) -> DecodeResult<f64> {
                 // is going to have a string here, as per JSON spec.
                 match std::str::from_str(s.as_slice()) {
                     Some(f) => Ok(f),
-                    None => Err(ExpectedError("Number".to_string(), s)),
+                    None => Err(ExpectedError("Number".into_string(), s)),
                 }
             },
             Json::Null => Ok(f64::NAN),
-            value => Err(ExpectedError("Number".to_string(), format!("{}", value)))
+            value => Err(ExpectedError("Number".into_string(), format!("{}", value)))
         }
     }
 
@@ -2046,7 +2044,7 @@ fn read_char(&mut self) -> DecodeResult<char> {
                 _ => ()
             }
         }
-        Err(ExpectedError("single character string".to_string(), format!("{}", s)))
+        Err(ExpectedError("single character string".into_string(), format!("{}", s)))
     }
 
     fn read_str(&mut self) -> DecodeResult<string::String> {
@@ -2069,32 +2067,32 @@ fn read_enum_variant<T>(&mut self,
         let name = match self.pop() {
             Json::String(s) => s,
             Json::Object(mut o) => {
-                let n = match o.remove(&"variant".to_string()) {
+                let n = match o.remove(&"variant".into_string()) {
                     Some(Json::String(s)) => s,
                     Some(val) => {
-                        return Err(ExpectedError("String".to_string(), format!("{}", val)))
+                        return Err(ExpectedError("String".into_string(), format!("{}", val)))
                     }
                     None => {
-                        return Err(MissingFieldError("variant".to_string()))
+                        return Err(MissingFieldError("variant".into_string()))
                     }
                 };
-                match o.remove(&"fields".to_string()) {
+                match o.remove(&"fields".into_string()) {
                     Some(Json::Array(l)) => {
                         for field in l.into_iter().rev() {
                             self.stack.push(field);
                         }
                     },
                     Some(val) => {
-                        return Err(ExpectedError("Array".to_string(), format!("{}", val)))
+                        return Err(ExpectedError("Array".into_string(), format!("{}", val)))
                     }
                     None => {
-                        return Err(MissingFieldError("fields".to_string()))
+                        return Err(MissingFieldError("fields".into_string()))
                     }
                 }
                 n
             }
             json => {
-                return Err(ExpectedError("String or Object".to_string(), format!("{}", json)))
+                return Err(ExpectedError("String or Object".into_string(), format!("{}", json)))
             }
         };
         let idx = match names.iter()
@@ -2443,9 +2441,9 @@ fn test_decode_option_some() {
     #[test]
     fn test_decode_option_malformed() {
         check_err::<OptionData>("{ \"opt\": [] }",
-                                ExpectedError("Number".to_string(), "[]".to_string()));
+                                ExpectedError("Number".into_string(), "[]".into_string()));
         check_err::<OptionData>("{ \"opt\": false }",
-                                ExpectedError("Number".to_string(), "false".to_string()));
+                                ExpectedError("Number".into_string(), "false".into_string()));
     }
 
     #[deriving(PartialEq, Encodable, Decodable, Show)]
@@ -2486,72 +2484,75 @@ fn test_from_str_trait() {
 
     #[test]
     fn test_write_null() {
-        assert_eq!(Null.to_string().into_string(), "null");
-        assert_eq!(Null.to_pretty_str().into_string(), "null");
+        assert_eq!(Null.to_string(), "null");
+        assert_eq!(Null.to_pretty_str(), "null");
     }
 
     #[test]
     fn test_write_i64() {
-        assert_eq!(U64(0).to_string().into_string(), "0");
-        assert_eq!(U64(0).to_pretty_str().into_string(), "0");
+        assert_eq!(U64(0).to_string(), "0");
+        assert_eq!(U64(0).to_pretty_str(), "0");
+
+        assert_eq!(U64(1234).to_string(), "1234");
+        assert_eq!(U64(1234).to_pretty_str(), "1234");
 
-        assert_eq!(U64(1234).to_string().into_string(), "1234");
-        assert_eq!(U64(1234).to_pretty_str().into_string(), "1234");
+        assert_eq!(I64(-5678).to_string(), "-5678");
+        assert_eq!(I64(-5678).to_pretty_str(), "-5678");
 
-        assert_eq!(I64(-5678).to_string().into_string(), "-5678");
-        assert_eq!(I64(-5678).to_pretty_str().into_string(), "-5678");
+        assert_eq!(U64(7650007200025252000).to_string(), "7650007200025252000");
+        assert_eq!(U64(7650007200025252000).to_pretty_str(), "7650007200025252000");
     }
 
     #[test]
     fn test_write_f64() {
-        assert_eq!(F64(3.0).to_string().into_string(), "3");
-        assert_eq!(F64(3.0).to_pretty_str().into_string(), "3");
+        assert_eq!(F64(3.0).to_string(), "3.0");
+        assert_eq!(F64(3.0).to_pretty_str(), "3.0");
 
-        assert_eq!(F64(3.1).to_string().into_string(), "3.1");
-        assert_eq!(F64(3.1).to_pretty_str().into_string(), "3.1");
+        assert_eq!(F64(3.1).to_string(), "3.1");
+        assert_eq!(F64(3.1).to_pretty_str(), "3.1");
 
-        assert_eq!(F64(-1.5).to_string().into_string(), "-1.5");
-        assert_eq!(F64(-1.5).to_pretty_str().into_string(), "-1.5");
+        assert_eq!(F64(-1.5).to_string(), "-1.5");
+        assert_eq!(F64(-1.5).to_pretty_str(), "-1.5");
 
-        assert_eq!(F64(0.5).to_string().into_string(), "0.5");
-        assert_eq!(F64(0.5).to_pretty_str().into_string(), "0.5");
+        assert_eq!(F64(0.5).to_string(), "0.5");
+        assert_eq!(F64(0.5).to_pretty_str(), "0.5");
 
-        assert_eq!(F64(f64::NAN).to_string().into_string(), "null");
-        assert_eq!(F64(f64::NAN).to_pretty_str().into_string(), "null");
+        assert_eq!(F64(f64::NAN).to_string(), "null");
+        assert_eq!(F64(f64::NAN).to_pretty_str(), "null");
 
-        assert_eq!(F64(f64::INFINITY).to_string().into_string(), "null");
-        assert_eq!(F64(f64::INFINITY).to_pretty_str().into_string(), "null");
+        assert_eq!(F64(f64::INFINITY).to_string(), "null");
+        assert_eq!(F64(f64::INFINITY).to_pretty_str(), "null");
 
-        assert_eq!(F64(f64::NEG_INFINITY).to_string().into_string(), "null");
-        assert_eq!(F64(f64::NEG_INFINITY).to_pretty_str().into_string(), "null");
+        assert_eq!(F64(f64::NEG_INFINITY).to_string(), "null");
+        assert_eq!(F64(f64::NEG_INFINITY).to_pretty_str(), "null");
     }
 
     #[test]
     fn test_write_str() {
-        assert_eq!(String("".to_string()).to_string().into_string(), "\"\"");
-        assert_eq!(String("".to_string()).to_pretty_str().into_string(), "\"\"");
+        assert_eq!(String("".into_string()).to_string(), "\"\"");
+        assert_eq!(String("".into_string()).to_pretty_str(), "\"\"");
 
-        assert_eq!(String("foo".to_string()).to_string().into_string(), "\"foo\"");
-        assert_eq!(String("foo".to_string()).to_pretty_str().into_string(), "\"foo\"");
+        assert_eq!(String("homura".into_string()).to_string(), "\"homura\"");
+        assert_eq!(String("madoka".into_string()).to_pretty_str(), "\"madoka\"");
     }
 
     #[test]
     fn test_write_bool() {
-        assert_eq!(Boolean(true).to_string().into_string(), "true");
-        assert_eq!(Boolean(true).to_pretty_str().into_string(), "true");
+        assert_eq!(Boolean(true).to_string(), "true");
+        assert_eq!(Boolean(true).to_pretty_str(), "true");
 
-        assert_eq!(Boolean(false).to_string().into_string(), "false");
-        assert_eq!(Boolean(false).to_pretty_str().into_string(), "false");
+        assert_eq!(Boolean(false).to_string(), "false");
+        assert_eq!(Boolean(false).to_pretty_str(), "false");
     }
 
     #[test]
     fn test_write_array() {
-        assert_eq!(Array(vec![]).to_string().into_string(), "[]");
-        assert_eq!(Array(vec![]).to_pretty_str().into_string(), "[]");
+        assert_eq!(Array(vec![]).to_string(), "[]");
+        assert_eq!(Array(vec![]).to_pretty_str(), "[]");
 
-        assert_eq!(Array(vec![Boolean(true)]).to_string().into_string(), "[true]");
+        assert_eq!(Array(vec![Boolean(true)]).to_string(), "[true]");
         assert_eq!(
-            Array(vec![Boolean(true)]).to_pretty_str().into_string(),
+            Array(vec![Boolean(true)]).to_pretty_str(),
             "\
             [\n  \
                 true\n\
@@ -2561,12 +2562,12 @@ fn test_write_array() {
         let long_test_array = Array(vec![
             Boolean(false),
             Null,
-            Array(vec![String("foo\nbar".to_string()), F64(3.5)])]);
+            Array(vec![String("foo\nbar".into_string()), F64(3.5)])]);
 
-        assert_eq!(long_test_array.to_string().into_string(),
+        assert_eq!(long_test_array.to_string(),
             "[false,null,[\"foo\\nbar\",3.5]]");
         assert_eq!(
-            long_test_array.to_pretty_str().into_string(),
+            long_test_array.to_pretty_str(),
             "\
             [\n  \
                 false,\n  \
@@ -2581,17 +2582,17 @@ fn test_write_array() {
 
     #[test]
     fn test_write_object() {
-        assert_eq!(mk_object(&[]).to_string().into_string(), "{}");
-        assert_eq!(mk_object(&[]).to_pretty_str().into_string(), "{}");
+        assert_eq!(mk_object(&[]).to_string(), "{}");
+        assert_eq!(mk_object(&[]).to_pretty_str(), "{}");
 
         assert_eq!(
             mk_object(&[
-                ("a".to_string(), Boolean(true))
-            ]).to_string().into_string(),
+                ("a".into_string(), Boolean(true))
+            ]).to_string(),
             "{\"a\":true}"
         );
         assert_eq!(
-            mk_object(&[("a".to_string(), Boolean(true))]).to_pretty_str(),
+            mk_object(&[("a".into_string(), Boolean(true))]).to_pretty_str(),
             "\
             {\n  \
                 \"a\": true\n\
@@ -2599,14 +2600,14 @@ fn test_write_object() {
         );
 
         let complex_obj = mk_object(&[
-                ("b".to_string(), Array(vec![
-                    mk_object(&[("c".to_string(), String("\x0c\r".to_string()))]),
-                    mk_object(&[("d".to_string(), String("".to_string()))])
+                ("b".into_string(), Array(vec![
+                    mk_object(&[("c".into_string(), String("\x0c\r".into_string()))]),
+                    mk_object(&[("d".into_string(), String("".into_string()))])
                 ]))
             ]);
 
         assert_eq!(
-            complex_obj.to_string().into_string(),
+            complex_obj.to_string(),
             "{\
                 \"b\":[\
                     {\"c\":\"\\f\\r\"},\
@@ -2615,7 +2616,7 @@ fn test_write_object() {
             }"
         );
         assert_eq!(
-            complex_obj.to_pretty_str().into_string(),
+            complex_obj.to_pretty_str(),
             "\
             {\n  \
                 \"b\": [\n    \
@@ -2630,10 +2631,10 @@ fn test_write_object() {
         );
 
         let a = mk_object(&[
-            ("a".to_string(), Boolean(true)),
-            ("b".to_string(), Array(vec![
-                mk_object(&[("c".to_string(), String("\x0c\r".to_string()))]),
-                mk_object(&[("d".to_string(), String("".to_string()))])
+            ("a".into_string(), Boolean(true)),
+            ("b".into_string(), Array(vec![
+                mk_object(&[("c".into_string(), String("\x0c\r".into_string()))]),
+                mk_object(&[("d".into_string(), String("".into_string()))])
             ]))
         ]);
 
@@ -2670,7 +2671,7 @@ fn test_write_enum() {
             "\"Dog\""
         );
 
-        let animal = Frog("Henry".to_string(), 349);
+        let animal = Frog("Henry".into_string(), 349);
         assert_eq!(
             with_str_writer(|writer| {
                 let mut encoder = Encoder::new(writer);
@@ -2695,14 +2696,14 @@ fn test_write_enum() {
 
     #[test]
     fn test_write_some() {
-        let value = Some("jodhpurs".to_string());
+        let value = Some("jodhpurs".into_string());
         let s = with_str_writer(|writer| {
             let mut encoder = Encoder::new(writer);
             value.encode(&mut encoder).unwrap();
         });
         assert_eq!(s, "\"jodhpurs\"");
 
-        let value = Some("jodhpurs".to_string());
+        let value = Some("jodhpurs".into_string());
         let s = with_str_writer(|writer| {
             let mut encoder = PrettyEncoder::new(writer);
             value.encode(&mut encoder).unwrap();
@@ -2827,6 +2828,9 @@ fn test_decode_numbers() {
 
         let v: i64 = super::decode("9223372036854775807").unwrap();
         assert_eq!(v, i64::MAX);
+
+        let res: DecodeResult<i64> = super::decode("765.25252");
+        assert_eq!(res, Err(ExpectedError("Integer".into_string(), "765.25252".into_string())));
     }
 
     #[test]
@@ -2834,16 +2838,16 @@ fn test_read_str() {
         assert_eq!(from_str("\""),    Err(SyntaxError(EOFWhileParsingString, 1, 2)));
         assert_eq!(from_str("\"lol"), Err(SyntaxError(EOFWhileParsingString, 1, 5)));
 
-        assert_eq!(from_str("\"\""), Ok(String("".to_string())));
-        assert_eq!(from_str("\"foo\""), Ok(String("foo".to_string())));
-        assert_eq!(from_str("\"\\\"\""), Ok(String("\"".to_string())));
-        assert_eq!(from_str("\"\\b\""), Ok(String("\x08".to_string())));
-        assert_eq!(from_str("\"\\n\""), Ok(String("\n".to_string())));
-        assert_eq!(from_str("\"\\r\""), Ok(String("\r".to_string())));
-        assert_eq!(from_str("\"\\t\""), Ok(String("\t".to_string())));
-        assert_eq!(from_str(" \"foo\" "), Ok(String("foo".to_string())));
-        assert_eq!(from_str("\"\\u12ab\""), Ok(String("\u12ab".to_string())));
-        assert_eq!(from_str("\"\\uAB12\""), Ok(String("\uAB12".to_string())));
+        assert_eq!(from_str("\"\""), Ok(String("".into_string())));
+        assert_eq!(from_str("\"foo\""), Ok(String("foo".into_string())));
+        assert_eq!(from_str("\"\\\"\""), Ok(String("\"".into_string())));
+        assert_eq!(from_str("\"\\b\""), Ok(String("\x08".into_string())));
+        assert_eq!(from_str("\"\\n\""), Ok(String("\n".into_string())));
+        assert_eq!(from_str("\"\\r\""), Ok(String("\r".into_string())));
+        assert_eq!(from_str("\"\\t\""), Ok(String("\t".into_string())));
+        assert_eq!(from_str(" \"foo\" "), Ok(String("foo".into_string())));
+        assert_eq!(from_str("\"\\u12ab\""), Ok(String("\u12ab".into_string())));
+        assert_eq!(from_str("\"\\uAB12\""), Ok(String("\uAB12".into_string())));
     }
 
     #[test]
@@ -2909,7 +2913,7 @@ fn test_decode_tuple() {
         assert_eq!(t, (1u, 2, 3))
 
         let t: (uint, string::String) = super::decode("[1, \"two\"]").unwrap();
-        assert_eq!(t, (1u, "two".to_string()));
+        assert_eq!(t, (1u, "two".into_string()));
     }
 
     #[test]
@@ -2939,22 +2943,22 @@ fn test_read_object() {
 
         assert_eq!(from_str("{}").unwrap(), mk_object(&[]));
         assert_eq!(from_str("{\"a\": 3}").unwrap(),
-                  mk_object(&[("a".to_string(), U64(3))]));
+                  mk_object(&[("a".into_string(), U64(3))]));
 
         assert_eq!(from_str(
                       "{ \"a\": null, \"b\" : true }").unwrap(),
                   mk_object(&[
-                      ("a".to_string(), Null),
-                      ("b".to_string(), Boolean(true))]));
+                      ("a".into_string(), Null),
+                      ("b".into_string(), Boolean(true))]));
         assert_eq!(from_str("\n{ \"a\": null, \"b\" : true }\n").unwrap(),
                   mk_object(&[
-                      ("a".to_string(), Null),
-                      ("b".to_string(), Boolean(true))]));
+                      ("a".into_string(), Null),
+                      ("b".into_string(), Boolean(true))]));
         assert_eq!(from_str(
                       "{\"a\" : 1.0 ,\"b\": [ true ]}").unwrap(),
                   mk_object(&[
-                      ("a".to_string(), F64(1.0)),
-                      ("b".to_string(), Array(vec![Boolean(true)]))
+                      ("a".into_string(), F64(1.0)),
+                      ("b".into_string(), Array(vec![Boolean(true)]))
                   ]));
         assert_eq!(from_str(
                       "{\
@@ -2966,12 +2970,12 @@ fn test_read_object() {
                           ]\
                       }").unwrap(),
                   mk_object(&[
-                      ("a".to_string(), F64(1.0)),
-                      ("b".to_string(), Array(vec![
+                      ("a".into_string(), F64(1.0)),
+                      ("b".into_string(), Array(vec![
                           Boolean(true),
-                          String("foo\nbar".to_string()),
+                          String("foo\nbar".into_string()),
                           mk_object(&[
-                              ("c".to_string(), mk_object(&[("d".to_string(), Null)]))
+                              ("c".into_string(), mk_object(&[("d".into_string(), Null)]))
                           ])
                       ]))
                   ]));
@@ -2990,7 +2994,7 @@ fn test_decode_struct() {
             v,
             Outer {
                 inner: vec![
-                    Inner { a: (), b: 2, c: vec!["abc".to_string(), "xyz".to_string()] }
+                    Inner { a: (), b: 2, c: vec!["abc".into_string(), "xyz".into_string()] }
                 ]
             }
         );
@@ -3016,7 +3020,7 @@ fn test_decode_option() {
         assert_eq!(value, None);
 
         let value: Option<string::String> = super::decode("\"jodhpurs\"").unwrap();
-        assert_eq!(value, Some("jodhpurs".to_string()));
+        assert_eq!(value, Some("jodhpurs".into_string()));
     }
 
     #[test]
@@ -3026,7 +3030,7 @@ fn test_decode_enum() {
 
         let s = "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}";
         let value: Animal = super::decode(s).unwrap();
-        assert_eq!(value, Frog("Henry".to_string(), 349));
+        assert_eq!(value, Frog("Henry".into_string(), 349));
     }
 
     #[test]
@@ -3035,8 +3039,8 @@ fn test_decode_map() {
                   \"fields\":[\"Henry\", 349]}}";
         let mut map: TreeMap<string::String, Animal> = super::decode(s).unwrap();
 
-        assert_eq!(map.remove(&"a".to_string()), Some(Dog));
-        assert_eq!(map.remove(&"b".to_string()), Some(Frog("Henry".to_string(), 349)));
+        assert_eq!(map.remove(&"a".into_string()), Some(Dog));
+        assert_eq!(map.remove(&"b".into_string()), Some(Frog("Henry".into_string(), 349)));
     }
 
     #[test]
@@ -3076,30 +3080,30 @@ fn check_err<T: Decodable<Decoder, DecoderError>>(to_parse: &'static str,
     }
     #[test]
     fn test_decode_errors_struct() {
-        check_err::<DecodeStruct>("[]", ExpectedError("Object".to_string(), "[]".to_string()));
+        check_err::<DecodeStruct>("[]", ExpectedError("Object".into_string(), "[]".into_string()));
         check_err::<DecodeStruct>("{\"x\": true, \"y\": true, \"z\": \"\", \"w\": []}",
-                                  ExpectedError("Number".to_string(), "true".to_string()));
+                                  ExpectedError("Number".into_string(), "true".into_string()));
         check_err::<DecodeStruct>("{\"x\": 1, \"y\": [], \"z\": \"\", \"w\": []}",
-                                  ExpectedError("Boolean".to_string(), "[]".to_string()));
+                                  ExpectedError("Boolean".into_string(), "[]".into_string()));
         check_err::<DecodeStruct>("{\"x\": 1, \"y\": true, \"z\": {}, \"w\": []}",
-                                  ExpectedError("String".to_string(), "{}".to_string()));
+                                  ExpectedError("String".into_string(), "{}".into_string()));
         check_err::<DecodeStruct>("{\"x\": 1, \"y\": true, \"z\": \"\", \"w\": null}",
-                                  ExpectedError("Array".to_string(), "null".to_string()));
+                                  ExpectedError("Array".into_string(), "null".into_string()));
         check_err::<DecodeStruct>("{\"x\": 1, \"y\": true, \"z\": \"\"}",
-                                  MissingFieldError("w".to_string()));
+                                  MissingFieldError("w".into_string()));
     }
     #[test]
     fn test_decode_errors_enum() {
         check_err::<DecodeEnum>("{}",
-                                MissingFieldError("variant".to_string()));
+                                MissingFieldError("variant".into_string()));
         check_err::<DecodeEnum>("{\"variant\": 1}",
-                                ExpectedError("String".to_string(), "1".to_string()));
+                                ExpectedError("String".into_string(), "1".into_string()));
         check_err::<DecodeEnum>("{\"variant\": \"A\"}",
-                                MissingFieldError("fields".to_string()));
+                                MissingFieldError("fields".into_string()));
         check_err::<DecodeEnum>("{\"variant\": \"A\", \"fields\": null}",
-                                ExpectedError("Array".to_string(), "null".to_string()));
+                                ExpectedError("Array".into_string(), "null".into_string()));
         check_err::<DecodeEnum>("{\"variant\": \"C\", \"fields\": []}",
-                                UnknownVariantError("C".to_string()));
+                                UnknownVariantError("C".into_string()));
     }
 
     #[test]
@@ -3384,7 +3388,7 @@ fn test_hashmap_with_numeric_key_will_error_with_string_keys() {
         };
         let mut decoder = Decoder::new(json_obj);
         let result: Result<HashMap<uint, bool>, DecoderError> = Decodable::decode(&mut decoder);
-        assert_eq!(result, Err(ExpectedError("Number".to_string(), "a".to_string())));
+        assert_eq!(result, Err(ExpectedError("Number".into_string(), "a".into_string())));
     }
 
     fn assert_stream_equal(src: &str,
@@ -3411,7 +3415,7 @@ fn test_streaming_parser() {
             r#"{ "foo":"bar", "array" : [0, 1, 2, 3, 4, 5], "idents":[null,true,false]}"#,
             vec![
                 (ObjectStart,             vec![]),
-                  (StringValue("bar".to_string()),   vec![Key("foo")]),
+                  (StringValue("bar".into_string()),   vec![Key("foo")]),
                   (ArrayStart,            vec![Key("array")]),
                     (U64Value(0),         vec![Key("array"), Index(0)]),
                     (U64Value(1),         vec![Key("array"), Index(1)]),
@@ -3502,7 +3506,7 @@ fn test_read_object_streaming() {
                   (F64Value(1.0),               vec![Key("a")]),
                   (ArrayStart,                  vec![Key("b")]),
                     (BooleanValue(true),        vec![Key("b"), Index(0)]),
-                    (StringValue("foo\nbar".to_string()),  vec![Key("b"), Index(1)]),
+                    (StringValue("foo\nbar".into_string()),  vec![Key("b"), Index(1)]),
                     (ObjectStart,               vec![Key("b"), Index(2)]),
                       (ObjectStart,             vec![Key("b"), Index(2), Key("c")]),
                         (NullValue,             vec![Key("b"), Index(2), Key("c"), Key("d")]),
@@ -3635,7 +3639,7 @@ fn test_stack() {
         assert!(stack.last_is_index());
         assert!(stack.get(0) == Index(1));
 
-        stack.push_key("foo".to_string());
+        stack.push_key("foo".into_string());
 
         assert!(stack.len() == 2);
         assert!(stack.is_equal_to(&[Index(1), Key("foo")]));
@@ -3647,7 +3651,7 @@ fn test_stack() {
         assert!(stack.get(0) == Index(1));
         assert!(stack.get(1) == Key("foo"));
 
-        stack.push_key("bar".to_string());
+        stack.push_key("bar".into_string());
 
         assert!(stack.len() == 3);
         assert!(stack.is_equal_to(&[Index(1), Key("foo"), Key("bar")]));
@@ -3684,8 +3688,8 @@ fn test_to_json() {
         let array3 = Array(vec!(U64(1), U64(2), U64(3)));
         let object = {
             let mut tree_map = TreeMap::new();
-            tree_map.insert("a".to_string(), U64(1));
-            tree_map.insert("b".to_string(), U64(2));
+            tree_map.insert("a".into_string(), U64(1));
+            tree_map.insert("b".into_string(), U64(2));
             Object(tree_map)
         };
 
@@ -3717,12 +3721,12 @@ fn test_to_json() {
         assert_eq!((vec![1u, 2]).to_json(), array2);
         assert_eq!(vec!(1u, 2, 3).to_json(), array3);
         let mut tree_map = TreeMap::new();
-        tree_map.insert("a".to_string(), 1u);
-        tree_map.insert("b".to_string(), 2);
+        tree_map.insert("a".into_string(), 1u);
+        tree_map.insert("b".into_string(), 2);
         assert_eq!(tree_map.to_json(), object);
         let mut hash_map = HashMap::new();
-        hash_map.insert("a".to_string(), 1u);
-        hash_map.insert("b".to_string(), 2);
+        hash_map.insert("a".into_string(), 1u);
+        hash_map.insert("b".into_string(), 2);
         assert_eq!(hash_map.to_json(), object);
         assert_eq!(Some(15i).to_json(), I64(15));
         assert_eq!(Some(15u).to_json(), U64(15));
@@ -3765,7 +3769,7 @@ fn bench_small(b: &mut Bencher) {
     }
 
     fn big_json() -> string::String {
-        let mut src = "[\n".to_string();
+        let mut src = "[\n".into_string();
         for _ in range(0i, 500) {
             src.push_str(r#"{ "a": true, "b": null, "c":3.1415, "d": "Hello world", "e": \
                             [1,2,3]},"#);
index 9711d5c7209be7c123c5910bbaea781adf9fdabc..1cff4c334e7430d1d8827e6e89281e0c862dc934 100644 (file)
@@ -23,7 +23,7 @@
        html_root_url = "http://doc.rust-lang.org/nightly/",
        html_playground_url = "http://play.rust-lang.org/")]
 #![allow(unknown_features)]
-#![feature(macro_rules, default_type_params, phase, slicing_syntax, globs)]
+#![feature(macro_rules, default_type_params, phase, slicing_syntax, globs, if_let)]
 
 // test harness access
 #[cfg(test)]
index 2872f74cf8878891d48b7153bfb8b08cbf947fae..23eb367dbd10a94d9f292fb9b8b8dfb25c78a9e1 100644 (file)
@@ -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 @@
 #[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]
index 8a90c06f0385c1395cc04dabd84af37a56e7defa..ffcd6505dadd1cab7a67fe42553de9c6f8e2dc10 100644 (file)
@@ -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 @@ fn not(&self) -> $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);
index de06a1e0bbd6e5bb33b99a4d1fcd285cdd9c9db3..ef4cabedc474ea34b789a4bc9108a13331c22e54 100644 (file)
@@ -16,7 +16,7 @@
 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<K, V> {
     val:  *mut V
 }
 
+impl<K,V> Copy for RawBucket<K,V> {}
+
 pub struct Bucket<K, V, M> {
     raw:   RawBucket<K, V>,
     idx:   uint,
     table: M
 }
 
+impl<K,V,M:Copy> Copy for Bucket<K,V,M> {}
+
 pub struct EmptyBucket<K, V, M> {
     raw:   RawBucket<K, V>,
     idx:   uint,
index d291ed7256743b224a8e4a4806ce5fb3a6871973..6cff5a3dd239dd15586491116bd1da1c79678008 100644 (file)
@@ -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)]
index aa0c8b53c2e897f4d123337156df11d828404a87..96b075ab569bf35827d0201ddcc472b64111f2c0 100644 (file)
 use mem;
 use ops::*;
 use option::*;
+use option::Option::{None, Some};
 use os;
 use path::{Path,GenericPath};
 use result::*;
+use result::Result::{Err, Ok};
 use slice::{AsSlice,SlicePrelude};
 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,8 +215,10 @@ pub mod dl {
 
     use c_str::{CString, ToCStr};
     use libc;
+    use kinds::Copy;
     use ptr;
     use result::*;
+    use result::Result::{Err, Ok};
     use string::String;
 
     pub unsafe fn open_external<T: ToCStr>(filename: T) -> *mut u8 {
@@ -262,6 +269,8 @@ pub enum Rtld {
         Local = 0,
     }
 
+    impl Copy for Rtld {}
+
     #[link_name = "dl"]
     extern {
         fn dlopen(filename: *const libc::c_char,
index d43a7a66c5b58355c08bfdcb97a7573fcf57a639..dc212e7cab3aed33a3c88b10e0acecb322f3f331 100644 (file)
 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<T> {
     /// 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 @@ pub struct UnstableFileStat {
     }
 }
 
+impl Copy for FilePermission {}
+
 impl Default for FilePermission {
     #[inline]
     fn default() -> FilePermission { FilePermission::empty() }
index fea8372733c29d7833f338b13c025d543f53dd46..fc81ab7b57a3ef34076a83acaa0c9a59e3546ab6 100644 (file)
@@ -22,6 +22,7 @@
 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<Vec<IpAddr>> {
index 3fa6f4a6091edbd856c8d1cc7b653f45bfa59e86..f59dd37c0da16cb493c3be5681e6f28924744ccf 100644 (file)
@@ -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 {
index 61ebfb06c71fed7a481a4381f1f33b57e2b8f0f4..c46a6e82e448661d3181b0f29535377fc1498760 100644 (file)
@@ -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 {
index e78bd1dd33f32c57a2ca662d7bb9236bdf1587b1..faa52226a03b7f996448b5eaa7b3650ad2ce83b0 100644 (file)
@@ -83,6 +83,8 @@ fn consume(&mut self, amt: uint) {
 /// 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 @@ fn write(&mut self, _buf: &[u8]) -> io::IoResult<()> { Ok(()) }
 /// 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<uint> {
@@ -111,6 +115,8 @@ fn consume(&mut self, _amt: uint) {}
 /// 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<uint> {
index c87f40f351bc013867ff7cb1c2063aaf8af14e55..1c9826ff5aca38be186c4d65b544b405ca73cd1c 100644 (file)
@@ -18,6 +18,7 @@
 
 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<T: Int>(num: T, radix: uint, sign: SignFormat, f: |u8|) {
     assert!(2 <= radix && radix <= 36);
 
index 2b904acb56520be2828aa01d3a0c15411b652d44..6c91010f4cb35730c82ff2dc5a804e06f134a0b1 100644 (file)
@@ -36,6 +36,7 @@
 use fmt;
 use io::{IoResult, IoError};
 use iter::{Iterator, IteratorExt};
+use kinds::Copy;
 use libc::{c_void, c_int};
 use libc;
 use boxed::Box;
@@ -159,7 +160,7 @@ pub fn getcwd() -> IoResult<Path> {
 }
 
 #[cfg(windows)]
-pub mod windows {
+pub mod windoze {
     use libc::types::os::arch::extra::DWORD;
     use libc;
     use option::Option;
@@ -385,7 +386,7 @@ pub fn getenv_as_bytes(n: &str) -> Option<Vec<u8>> {
 pub fn getenv(n: &str) -> Option<String> {
     unsafe {
         with_env_lock(|| {
-            use os::windows::{fill_utf16_buf_and_decode};
+            use os::windoze::{fill_utf16_buf_and_decode};
             let mut n: Vec<u16> = n.utf16_units().collect();
             n.push(0);
             fill_utf16_buf_and_decode(|buf, sz| {
@@ -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
@@ -712,7 +715,7 @@ fn load_self() -> Option<Vec<u8>> {
     #[cfg(windows)]
     fn load_self() -> Option<Vec<u8>> {
         unsafe {
-            use os::windows::fill_utf16_buf_and_decode;
+            use os::windoze::fill_utf16_buf_and_decode;
             fill_utf16_buf_and_decode(|buf, sz| {
                 libc::GetModuleFileNameW(0u as libc::DWORD, buf, sz)
             }).map(|s| s.into_string().into_bytes())
@@ -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
@@ -1207,7 +1215,11 @@ pub enum MapOption {
     /// Create a map for a specific address range. Corresponds to `MAP_FIXED` on
     /// POSIX.
     MapAddr(*const u8),
+    /// Create a memory mapping for a file with a given HANDLE.
+    #[cfg(windows)]
+    MapFd(libc::HANDLE),
     /// Create a memory mapping for a file with a given fd.
+    #[cfg(not(windows))]
     MapFd(c_int),
     /// When using `MapFd`, the start of the map is `uint` bytes from the start
     /// of the file.
@@ -1219,6 +1231,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 +1278,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 {
@@ -1401,7 +1417,7 @@ pub fn new(min_len: uint, options: &[MapOption]) -> Result<MemoryMap, MapError>
         let mut readable = false;
         let mut writable = false;
         let mut executable = false;
-        let mut fd: c_int = -1;
+        let mut handle: HANDLE = libc::INVALID_HANDLE_VALUE;
         let mut offset: uint = 0;
         let len = round_up(min_len, page_size());
 
@@ -1411,23 +1427,23 @@ pub fn new(min_len: uint, options: &[MapOption]) -> Result<MemoryMap, MapError>
                 MapWritable => { writable = true; },
                 MapExecutable => { executable = true; }
                 MapAddr(addr_) => { lpAddress = addr_ as LPVOID; },
-                MapFd(fd_) => { fd = fd_; },
+                MapFd(handle_) => { handle = handle_; },
                 MapOffset(offset_) => { offset = offset_; },
                 MapNonStandardFlags(..) => {}
             }
         }
 
         let flProtect = match (executable, readable, writable) {
-            (false, false, false) if fd == -1 => libc::PAGE_NOACCESS,
+            (false, false, false) if handle == libc::INVALID_HANDLE_VALUE => libc::PAGE_NOACCESS,
             (false, true, false) => libc::PAGE_READONLY,
             (false, true, true) => libc::PAGE_READWRITE,
-            (true, false, false) if fd == -1 => libc::PAGE_EXECUTE,
+            (true, false, false) if handle == libc::INVALID_HANDLE_VALUE => libc::PAGE_EXECUTE,
             (true, true, false) => libc::PAGE_EXECUTE_READ,
             (true, true, true) => libc::PAGE_EXECUTE_READWRITE,
             _ => return Err(ErrUnsupProt)
         };
 
-        if fd == -1 {
+        if handle == libc::INVALID_HANDLE_VALUE {
             if offset != 0 {
                 return Err(ErrUnsupOffset);
             }
@@ -1455,7 +1471,7 @@ pub fn new(min_len: uint, options: &[MapOption]) -> Result<MemoryMap, MapError>
                                               // we should never get here.
             };
             unsafe {
-                let hFile = libc::get_osfhandle(fd) as HANDLE;
+                let hFile = handle;
                 let mapping = libc::CreateFileMappingW(hFile,
                                                        ptr::null_mut(),
                                                        flProtect,
@@ -1979,55 +1995,47 @@ fn memory_map_rw() {
 
     #[test]
     fn memory_map_file() {
-        use result::Result::{Ok, Err};
+        use libc;
         use os::*;
-        use libc::*;
-        use io::fs;
-
-        #[cfg(unix)]
-        fn lseek_(fd: c_int, size: uint) {
-            unsafe {
-                assert!(lseek(fd, size as off_t, SEEK_SET) == size as off_t);
-            }
+        use io::fs::{File, unlink};
+        use io::SeekStyle::SeekSet;
+        use io::FileMode::Open;
+        use io::FileAccess::ReadWrite;
+
+        #[cfg(not(windows))]
+        fn get_fd(file: &File) -> libc::c_int {
+            use os::unix::AsRawFd;
+            file.as_raw_fd()
         }
+
         #[cfg(windows)]
-        fn lseek_(fd: c_int, size: uint) {
-           unsafe {
-               assert!(lseek(fd, size as c_long, SEEK_SET) == size as c_long);
-           }
+        fn get_fd(file: &File) -> libc::HANDLE {
+            use os::windows::AsRawHandle;
+            file.as_raw_handle()
         }
 
         let mut path = tmpdir();
         path.push("mmap_file.tmp");
         let size = MemoryMap::granularity() * 2;
+        let mut file = File::open_mode(&path, Open, ReadWrite).unwrap();
+        file.seek(size as i64, SeekSet);
+        file.write_u8(0);
 
-        let fd = unsafe {
-            let fd = path.with_c_str(|path| {
-                open(path, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR)
-            });
-            lseek_(fd, size);
-            "x".with_c_str(|x| assert!(write(fd, x as *const c_void, 1) == 1));
-            fd
-        };
-        let chunk = match MemoryMap::new(size / 2, &[
+        let chunk = MemoryMap::new(size / 2, &[
             MapReadable,
             MapWritable,
-            MapFd(fd),
+            MapFd(get_fd(&file)),
             MapOffset(size / 2)
-        ]) {
-            Ok(chunk) => chunk,
-            Err(msg) => panic!("{}", msg)
-        };
+        ]).unwrap();
         assert!(chunk.len > 0);
 
         unsafe {
             *chunk.data = 0xbe;
             assert!(*chunk.data == 0xbe);
-            close(fd);
         }
         drop(chunk);
 
-        fs::unlink(&path).unwrap();
+        unlink(&path).unwrap();
     }
 
     #[test]
index b53e6b2a5e07c7d615d9e19c6ee7f17f51d101b4..ea522536d22fd5f9b78fc839c5dd10466be8309e 100644 (file)
@@ -22,6 +22,7 @@
 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<PathPrefix> {
     if path.starts_with("\\\\") {
         // \\
index cc3c46f3610efd2ce63086301316e0180ec5266c..5b5fa2952e6bd06bcbe12f0a93cfd769c72e14cf 100644 (file)
@@ -80,7 +80,7 @@
 //! circle, both centered at the origin. Since the area of a unit circle is π,
 //! we have:
 //!
-//! ```notrust
+//! ```text
 //!     (area of unit circle) / (area of square) = π / 4
 //! ```
 //!
 use clone::Clone;
 use io::IoResult;
 use iter::{Iterator, IteratorExt};
+use kinds::Copy;
 use mem;
 use rc::Rc;
 use result::Result::{Ok, Err};
 
 /// 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`.
index eb46fd771477e6df7349f00258478993e077dee4..ee1515566204b0c545e935c8588e183aef563cbe 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use option::None;
+use option::Option::None;
 use rustrt::task::Task;
 use rustrt::local::Local;
 
index 370d74cc5e1898da87af6ce1e999025cfb3b833a..3eb0e3f46cb90e81cdb229ecb0251e18ad5d291b 100644 (file)
@@ -185,7 +185,23 @@ unsafe fn key(&self) -> imp::Key {
     }
 
     unsafe fn lazy_init(&self) -> uint {
-        let key = imp::create(self.dtor);
+        // POSIX allows the key created here to be 0, but the compare_and_swap
+        // below relies on using 0 as a sentinel value to check who won the
+        // race to set the shared TLS key. As far as I know, there is no
+        // guaranteed value that cannot be returned as a posix_key_create key,
+        // so there is no value we can initialize the inner key with to
+        // prove that it has not yet been set. As such, we'll continue using a
+        // value of 0, but with some gyrations to make sure we have a non-0
+        // value returned from the creation routine.
+        // FIXME: this is clearly a hack, and should be cleaned up.
+        let key1 = imp::create(self.dtor);
+        let key = if key1 != 0 {
+            key1
+        } else {
+            let key2 = imp::create(self.dtor);
+            imp::destroy(key1);
+            key2
+        };
         assert!(key != 0);
         match self.inner.key.compare_and_swap(0, key as uint, atomic::SeqCst) {
             // The CAS succeeded, so we've created the actual key
index 16779a80185bc8c8aababbfd1ae82368c69ed225..05be8de0b56e2e81db34f2c2274f1c4eb99b9921 100644 (file)
@@ -15,7 +15,7 @@
 
 use c_str::CString;
 use mem;
-use os::windows::fill_utf16_buf_and_decode;
+use os::windoze::fill_utf16_buf_and_decode;
 use path;
 use ptr;
 use str;
index 86c3a1fdd329598018c4f53f239aa9e6d1787fd9..7e6065129a384ad81bfe36ae5b973a23034b55cc 100644 (file)
@@ -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 struct 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.
index 87693f39bbdb1b74b3d5440de86d37cdfbeed697..71d29bca401ccf9a401a0cef22312d455afe0883 100644 (file)
 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
index 7e421df505d6c8c98426fc86c9e554528fa002ee..0a04a953b314fdd465637117e1adfef90a2b8a28 100644 (file)
@@ -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 @@ fn ne(&self, other: &Ident) -> bool {
 #[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<Stmt_>;
 
 #[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 <pat>:<ty> = <expr>;`
@@ -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<Lit_>;
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
@@ -903,7 +936,9 @@ pub enum Sign {
     Plus
 }
 
-impl<T: Int> Sign {
+impl Copy for Sign {}
+
+impl<T> 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.
index 8db12fbd8355ff8516d36a6bebeaa42a50e9b2af..639a33a806395ed967212a87d58541a0fb1e1020 100644 (file)
@@ -43,6 +43,8 @@
 /// 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 {
index ce2fe6e72209602e80d2eea1fafbc3db44726eee..2c985f403f8516a452aebefb1dad39ac0f7c0930 100644 (file)
@@ -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
index 68bb7ecfb8526d9e3b3665a4243916a4a83c5e8f..7dba6a57fc4c9ee2ae4dc8afaeb37ab4c2f0c0eb 100644 (file)
@@ -315,6 +315,8 @@ pub struct IdRange {
     pub max: NodeId,
 }
 
+impl Copy for IdRange {}
+
 impl IdRange {
     pub fn max() -> IdRange {
         IdRange {
index a2811681efd37591a25d6a9d4d5861f21042f2ff..5894a88ece65ab8fb326d50208784ffebfd182a1 100644 (file)
@@ -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 {
index 6bcf562204bed08bc96956ce8a765624c6f741ae..50b4f3423688cdf71e5ebcf48628955afa5c2602 100644 (file)
@@ -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<T> {
     pub span: Span,
 }
 
+impl<T:Copy> Copy for Spanned<T> {}
+
 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
index 293c1b3a9530fbc0f2e708a0125f77c4232eaeb2..bbda80bd96c33c461e9b7e2352cc79b86a9793ef 100644 (file)
@@ -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 @@ fn custom_emit(&mut self, cm: &codemap::CodeMap,
 /// 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;
index 0787518f04fb6fe43bb4dfd99139bc43db26f915..3c7a4a81d208fa9012360d77ec0d228fbfa70b88 100644 (file)
@@ -57,7 +57,7 @@ fn expand(&self,
               meta_item: &ast::MetaItem,
               item: &ast::Item,
               push: |P<ast::Item>|) {
-        (*self)(ecx, sp, meta_item, item, push)
+        self.clone()(ecx, sp, meta_item, item, push)
     }
 }
 
@@ -77,7 +77,7 @@ fn expand(&self,
               meta_item: &ast::MetaItem,
               item: P<ast::Item>)
               -> P<ast::Item> {
-        (*self)(ecx, span, meta_item, item)
+        self.clone()(ecx, span, meta_item, item)
     }
 }
 
@@ -99,7 +99,7 @@ fn expand<'cx>(&self,
                    span: Span,
                    token_tree: &[ast::TokenTree])
                    -> Box<MacResult+'cx> {
-        (*self)(ecx, span, token_tree)
+        self.clone()(ecx, span, token_tree)
     }
 }
 
@@ -122,7 +122,7 @@ fn expand<'cx>(&self,
                    ident: ast::Ident,
                    token_tree: Vec<ast::TokenTree> )
                    -> Box<MacResult+'cx> {
-        (*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.
     ///
index 787c6e844d5141e53f87059d6fe70ab890e3af66..1bd55b5d5045130a66e3a8b2beced966f2052b05 100644 (file)
@@ -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,
index 83af45462ec6e212a3cac37da74dc15222ed459b..6900773f44d4bec09aeba6251d00e03c145b4b13 100644 (file)
@@ -66,12 +66,19 @@ pub fn cs_cmp(cx: &mut ExtCtxt, span: Span,
                                           cx.ident_of("cmp"),
                                           cx.ident_of("Equal")));
 
+    let cmp_path = vec![
+        cx.ident_of("std"),
+        cx.ident_of("cmp"),
+        cx.ident_of("Ord"),
+        cx.ident_of("cmp"),
+    ];
+
     /*
     Builds:
 
-    let __test = self_field1.cmp(&other_field2);
+    let __test = ::std::cmp::Ord::cmp(&self_field1, &other_field1);
     if other == ::std::cmp::Ordering::Equal {
-        let __test = self_field2.cmp(&other_field2);
+        let __test = ::std::cmp::Ord::cmp(&self_field2, &other_field2);
         if __test == ::std::cmp::Ordering::Equal {
             ...
         } else {
@@ -83,11 +90,11 @@ pub fn cs_cmp(cx: &mut ExtCtxt, span: Span,
 
     FIXME #6449: These `if`s could/should be `match`es.
     */
-    cs_same_method_fold(
+    cs_fold(
         // foldr nests the if-elses correctly, leaving the first field
         // as the outermost one, and the last as the innermost.
         false,
-        |cx, span, old, new| {
+        |cx, span, old, self_f, other_fs| {
             // let __test = new;
             // if __test == ::std::cmp::Ordering::Equal {
             //    old
@@ -95,6 +102,20 @@ pub fn cs_cmp(cx: &mut ExtCtxt, span: Span,
             //    __test
             // }
 
+            let new = {
+                let other_f = match other_fs {
+                    [ref o_f] => o_f,
+                    _ => cx.span_bug(span, "not exactly 2 arguments in `deriving(PartialOrd)`"),
+                };
+
+                let args = vec![
+                    cx.expr_addr_of(span, self_f),
+                    cx.expr_addr_of(span, other_f.clone()),
+                ];
+
+                cx.expr_call_global(span, cmp_path.clone(), args)
+            };
+
             let assign = cx.stmt_let(span, false, test_id, new);
 
             let cond = cx.expr_binary(span, ast::BiEq,
index 6ba90bbebed01fa3928c2af41dadee177211797b..48120b575acd2fd10d4344c217a057b31aa8bb82 100644 (file)
@@ -56,6 +56,8 @@ pub enum SyntaxContext_ {
     IllegalCtxt
 }
 
+impl Copy for SyntaxContext_ {}
+
 /// A list of ident->name renamings
 pub type RenameList = Vec<(Ident, Name)>;
 
index 4af7b35079a63ffa2cddaeb27b2ce21cf6aa598e..b8f60e77601cfb63b51d53d40073977c5e17877b 100644 (file)
@@ -75,6 +75,9 @@
     // 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,8 +104,11 @@ pub struct Features {
     pub import_shadowing: bool,
     pub visible_private_types: bool,
     pub quote: bool,
+    pub opt_out_copy: bool,
 }
 
+impl Copy for Features {}
+
 impl Features {
     pub fn new() -> Features {
         Features {
@@ -112,6 +118,7 @@ pub fn new() -> Features {
             import_shadowing: false,
             visible_private_types: false,
             quote: false,
+            opt_out_copy: false,
         }
     }
 }
@@ -439,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)
 }
index aeec6ee13fd410601ad7914e162eab57c15e1d69..a17d66476c08c632b38d6d3ce72cae597b1c03f8 100644 (file)
@@ -36,6 +36,8 @@ pub enum CommentStyle {
     BlankLine,
 }
 
+impl Copy for CommentStyle {}
+
 #[deriving(Clone)]
 pub struct Comment {
     pub style: CommentStyle,
index ab2c15d54c5ef162c3af365ed2119b9451793f1a..2a77e3e67915bb92b46fc42d20eced6281db784e 100644 (file)
@@ -763,7 +763,7 @@ fn scan_hex_digits(&mut self,
         }
     }
 
-    // SNAP 361baab
+    // SNAP c9f6d69
     #[allow(unused)]
     fn old_escape_warning(&mut self, sp: Span) {
         self.span_diagnostic
@@ -796,7 +796,7 @@ fn scan_char_or_byte(&mut self, start: BytePos, first_source_char: char,
                                     self.scan_unicode_escape(delim)
                                 } else {
                                     let res = self.scan_hex_digits(4u, delim, false);
-                                    // SNAP 361baab
+                                    // SNAP c9f6d69
                                     //let sp = codemap::mk_sp(escaped_pos, self.last_pos);
                                     //self.old_escape_warning(sp);
                                     res
@@ -804,7 +804,7 @@ fn scan_char_or_byte(&mut self, start: BytePos, first_source_char: char,
                             }
                             'U' if !ascii_only => {
                                 let res = self.scan_hex_digits(8u, delim, false);
-                                // SNAP 361baab
+                                // SNAP c9f6d69
                                 //let sp = codemap::mk_sp(escaped_pos, self.last_pos);
                                 //self.old_escape_warning(sp);
                                 res
index 650f8295d01a6df3bd2bd636d7fc1d3dd8664741..2a2bb42cef012de88234cdcc487b8f74b44f45f1 100644 (file)
@@ -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);
index bb3d28ce2bb54c315f3a83ab215a813b45f5f53d..4929ee885acf972bb9d3324ed59507a8193695b2 100644 (file)
@@ -98,6 +98,8 @@
     }
 }
 
+impl Copy for Restrictions {}
+
 type ItemInfo = (Ident, Item_, Option<Vec<Attribute> >);
 
 /// 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.
index 52b54bc7f2d6dc81cde165c9a90757a869b1cbbb..4b1e9482a7d4981fd14c82953630f8a8abea7fd8 100644 (file)
@@ -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 @@ pub fn short_name(&self) -> &'static str {
     }
 }
 
+#[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 @@ pub enum Keyword {
             $( $rk_variant, )*
         }
 
+        impl Copy for Keyword {}
+
         impl Keyword {
             pub fn to_name(&self) -> ast::Name {
                 match *self {
index 7ab3d5dbcd1b5f386bea93d159605c30c65faa69..c4e040a0f7c1aafd6df28d104e151491c792ea6f 100644 (file)
@@ -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<io::Writer+'static>, linewidth: uint) -> Printer {
index 6ce0ee79c6230c41e003ced1c865708e6fff92b0..eab03f73091744a046d265ad8439a57852e2c2e9 100644 (file)
@@ -47,6 +47,8 @@ fn post(&self, _state: &mut State, _node: AnnNode) -> IoResult<()> { Ok(()) }
 
 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>,
index 18623ca2a81e2078e611b515342793935c8f5515..f5e89dd61ff7ef041a755f5aef76d1a9e5d4674c 100644 (file)
@@ -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;
index 0e4ecb8f73e48f19d45a02a6fd034020b79436bf..575ec860f973ee16da5a4e675009705cba185dfb 100644 (file)
@@ -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 enum 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
index ee8178fed915fc6710d5be5fc85f056748d24a96..c81bff6a1aeb3897fa8a00ba4762a47c40bd463e 100644 (file)
@@ -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 {
index 06105ca61ca66264e5a98e41b03ccc9766d423a9..ffc26738dd7b2d7ca23d73eb9f98d08e833751c8 100644 (file)
@@ -109,7 +109,13 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 #[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 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 /// 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<String,MetricChange>;
 
 // 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<Regex>,
     pub run_ignored: bool,
@@ -1135,7 +1148,7 @@ fn run_test_inner(desc: TestDesc,
             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;
         }
index 4453034fe06deb1e6323f3ac5011b3a1c761197d..e293c547944d535a204b08f9e439228ee52d502f 100644 (file)
@@ -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 {
index c91ce5c6464e854fd2aa5087f5aba9e2b12a7408..54f7b3501b805be56c6fac62871cf0b186283fa2 100644 (file)
@@ -7138,6 +7138,7 @@ pub fn width(c: char, is_cjk: bool) -> Option<uint> {
 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 enum GraphemeCat {
         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, _)| {
index a1a840b4deb1b50ec58d351f3657e0d8ea0a86ce..0faf6840f0610f095d68c1b2ac6e393ffbcac82d 100644 (file)
@@ -1,12 +1,3 @@
-S 2014-12-05 361baab
-  freebsd-x86_64 73cbae4168538a07facd81cca45ed672badb7c3a
-  linux-i386 211cf0fbdbc7045b765e7b92d92049bbe6788513
-  linux-x86_64 f001cec306fc1ac77504884acf5dac2e7b39e164
-  macos-i386 751dc02fac96114361c56eb45ce52e7a58d555e0
-  macos-x86_64 58cad0275d7b33412501d7dd3386b924d2304e83
-  winnt-i386 872c56b88cebd7d590fd00bcbd264f0003b4427b
-  winnt-x86_64 2187d8b3187c03f95cd4e56a582f55ec0cfa8df9
-
 S 2014-11-21 c9f6d69
   freebsd-x86_64 0ef316e7c369177de043e69e964418bd637cbfc0
   linux-i386 c8342e762a1720be939ed7c6a39bdaa27892f66f
index 04e1d99301108c9f7ceefb6671b382a84e041783..9ecb1195de00ae88cc30dcf2d927f9d0a2c47c29 100644 (file)
@@ -25,6 +25,8 @@ pub mod hidden_core {
 
         pub struct A;
 
+        impl Copy for A {}
+
         pub fn make() -> B { A }
 
         impl A {
index 5bd52ef501068c80decef3ebc60fc75b8b8735df..cf8d0c167a1ceb784f18a15e7375d5923bbaa90e 100644 (file)
@@ -22,6 +22,10 @@ pub struct P {
         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 {}
+
index ea2461ccfa8efc280ce2a96e30c59ddca818fcaf..e6bae4628874c46b5ad0daf800589b32835786a0 100644 (file)
@@ -22,3 +22,8 @@ fn panic(_: &(&'static str, &'static str, uint)) -> ! { loop {} }
 
 #[lang = "eh_personality"]
 extern fn eh_personality() {}
+
+#[lang="copy"]
+pub trait Copy {}
+
+
index d02222931e5de093ad3ab8cb2b814b3a942bdadd..37022131c3d94de15f7a118344a38ad436a1e726 100644 (file)
@@ -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; }
index 99eb665388b26c721ff2cb707ea48a91f517a730..e1e79b59e3e443926edf30c942edb2560e7a03bb 100644 (file)
@@ -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; }
index d56d7a70edfc863b6ff4565209588ac1a9f7ca59..5a918db1cfa20a04e5816517974da2c2b1a32d5d 100644 (file)
 
 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 {}
+
index 419e39b53cf81bc39e8b7202e2bb3d589eca2a46..025f8467d206770d9dac925306b04d2e2e554a38 100644 (file)
@@ -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) }
index 3059a014528ad288a7bad919e13702d482b640f8..e954d0fed5e593e323a1a07757bc97ed7e6d7b4c 100644 (file)
@@ -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<Color>) -> String {
     let mut out = String::new();
     for col in set.iter() {
index b38b8e66d7dbdb980d6a86a1077186b55df394f1..4b890bbd8d30e94cf18d4c2daa014e936203ceb2 100644 (file)
@@ -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];
index 0b4a1d91968d28555d1be56b08ef2128624237d8..afffbe5bed4e42dfff0f2c2eb0d7331c6ea3264c 100644 (file)
@@ -109,6 +109,8 @@ struct AminoAcid {
     p: f32,
 }
 
+impl Copy for AminoAcid {}
+
 struct RepeatFasta<'a, W:'a> {
     alu: &'static str,
     out: &'a mut W
index 8ed041513c47c45a2ef7006660ecba830c17832f..847ae2c1c88cc0722ec0275a9109edc0280e97c9 100644 (file)
@@ -62,6 +62,8 @@
 #[deriving(PartialEq, PartialOrd, Ord, Eq)]
 struct Code(u64);
 
+impl Copy for Code {}
+
 impl Code {
     fn hash(&self) -> u64 {
         let Code(ret) = *self;
index b62504d7ba85d901c1c28a5b563037ab48a8b737..3f36c16aff63fd9f58e82071e01c915bf5ebd5b3 100644 (file)
@@ -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();
index c071691c94707c0a27c8b2578096fb89495c829d..d5998c8ca99358231c21903f5ba4555018c50ae4 100644 (file)
@@ -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<Foo> { panic!() }
 
 fn borrow_same_field_twice_mut_mut() {
index 3a85b45ad126dffe44dcaede60251ddfb7ed67fc..d252d442297925941d725a9bd973f6a23a34fc41 100644 (file)
@@ -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 (file)
index 2063d73..0000000
+++ /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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-enum Either<T, U> { Left(T), Right(U) }
-
-    fn f(x: &mut Either<int,f64>, y: &Either<int,f64>) -> int {
-        match *y {
-            Either::Left(ref z) => {
-                *x = Either::Right(1.0);
-                *z
-            }
-            _ => panic!()
-        }
-    }
-
-    fn g() {
-        let mut x: Either<int,f64> = Either::Left(3);
-        println!("{}", f(&mut x, &x)); //~ ERROR cannot borrow
-    }
-
-    fn h() {
-        let mut x: Either<int,f64> = Either::Left(3);
-        let y: &Either<int, f64> = &x;
-        let z: &mut Either<int, f64> = &mut x; //~ ERROR cannot borrow
-        *z = *y;
-    }
-
-    fn main() {}
index 7414bb930d4d6e87b497f719cd6928fb1ee08861..0d27473cb2d02547edd87a916f56c69a0b3fcde4 100644 (file)
@@ -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<int> }
 
 fn var_copy_after_var_borrow() {
index f6511d68662eea478baea35e26ee5baf6f036f06..af97c864dc81a9b88a2bbbc060b4cbff3b555d07 100644 (file)
@@ -16,6 +16,8 @@
 
 struct S;
 
+impl Copy for S {}
+
 impl Index<uint, str> for S {
     fn index<'a>(&'a self, _: &uint) -> &'a str {
         "hello"
@@ -24,6 +26,8 @@ fn index<'a>(&'a self, _: &uint) -> &'a str {
 
 struct T;
 
+impl Copy for T {}
+
 impl Index<uint, Show + 'static> for T {
     fn index<'a>(&'a self, idx: &uint) -> &'a (Show + 'static) {
         static x: uint = 42;
@@ -33,7 +37,8 @@ fn index<'a>(&'a self, idx: &uint) -> &'a (Show + 'static) {
 
 fn main() {
     S[0];
-    //~^ ERROR E0161
+    //~^ ERROR cannot move out of dereference
+    //~^^ ERROR E0161
     T[0];
     //~^ ERROR cannot move out of dereference
     //~^^ ERROR E0161
index 52b7ea9efa5ed546c2e106fdadfa70803a9a716a..4c1dafd8c1a49c0be7c4ab63bce76e4efc6784f1 100644 (file)
 pub fn main() {
     let _x: Box<str> = 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
 }
index 3f69cb6e51ea296debafb182374444556bb78bbd..6b334dd6ecdfc0689ca704d1ed00aa2380e1031e 100644 (file)
@@ -20,5 +20,5 @@ fn drop(&mut self) {
 
 fn main() {
     let x = Foo { x: 3 };
-    x.drop();   //~ ERROR explicit call to destructor
+    x.drop();   //~ ERROR explicit use of destructor method
 }
index 3d987bf4c58a2be9aae93d88116aa706fbb9838d..d0dd0e68da6bd363ed54dd39cfd36b8c8c764175 100644 (file)
@@ -24,7 +24,7 @@ fn drop(&mut self) {
 
 impl Bar for Foo {
     fn blah(&self) {
-        self.drop();    //~ ERROR explicit call to destructor
+        self.drop();    //~ ERROR explicit use of destructor method
     }
 }
 
diff --git a/src/test/compile-fail/feature-gate-unboxed-closures-manual-impls.rs b/src/test/compile-fail/feature-gate-unboxed-closures-manual-impls.rs
new file mode 100644 (file)
index 0000000..8999da5
--- /dev/null
@@ -0,0 +1,26 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(dead_code)]
+
+struct Foo;
+impl Fn<(), ()> for Foo { //~ ERROR manual implementations of `Fn` are experimental
+    extern "rust-call" fn call(&self, args: ()) -> () {}
+}
+struct Bar;
+impl FnMut<(), ()> for Bar { //~ ERROR manual implementations of `FnMut` are experimental
+    extern "rust-call" fn call_mut(&self, args: ()) -> () {}
+}
+struct Baz;
+impl FnOnce<(), ()> for Baz { //~ ERROR manual implementations of `FnOnce` are experimental
+    extern "rust-call" fn call_once(&self, args: ()) -> () {}
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/feature-gate-unboxed-closures-method-calls.rs b/src/test/compile-fail/feature-gate-unboxed-closures-method-calls.rs
new file mode 100644 (file)
index 0000000..5a066c4
--- /dev/null
@@ -0,0 +1,19 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(dead_code)]
+
+fn foo<F: Fn<(), ()>>(mut f: F) {
+    f.call(()); //~ ERROR explicit use of unboxed closure method `call`
+    f.call_mut(()); //~ ERROR explicit use of unboxed closure method `call_mut`
+    f.call_once(()); //~ ERROR explicit use of unboxed closure method `call_once`
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/feature-gate-unboxed-closures-ufcs-calls.rs b/src/test/compile-fail/feature-gate-unboxed-closures-ufcs-calls.rs
new file mode 100644 (file)
index 0000000..8efaf00
--- /dev/null
@@ -0,0 +1,19 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(dead_code)]
+
+fn foo<F: Fn<(), ()>>(mut f: F, mut g: F) {
+    Fn::call(&g, ()); //~ ERROR explicit use of unboxed closure method `call`
+    FnMut::call_mut(&mut g, ()); //~ ERROR explicit use of unboxed closure method `call_mut`
+    FnOnce::call_once(g, ()); //~ ERROR explicit use of unboxed closure method `call_once`
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/illegal-ufcs-drop.rs b/src/test/compile-fail/illegal-ufcs-drop.rs
new file mode 100644 (file)
index 0000000..f4c653b
--- /dev/null
@@ -0,0 +1,20 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+struct Foo;
+
+impl Drop for Foo {
+    fn drop(&mut self) {}
+}
+
+fn main() {
+    Drop::drop(&mut Foo) //~ ERROR explicit use of destructor method
+}
index ef8174a26aa8206964e2a9c98d86946f38513f44..ab396edddf49c1031dce42f0a69a9a6d1ff952f0 100644 (file)
@@ -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]
 }
index f0c4a4243acc977e62897556d38544cf8f8c75f3..8868c7f8256da5b646386e049ae389a028c9de66 100644 (file)
@@ -14,6 +14,7 @@
 use std::rc::Rc;
 
 fn assert_copy<T:Copy>() { }
+
 trait Dummy { }
 
 struct MyStruct {
@@ -21,6 +22,8 @@ struct MyStruct {
     y: int,
 }
 
+impl Copy for MyStruct {}
+
 struct MyNoncopyStruct {
     x: Box<char>,
 }
index 5d96176434239cdcf6adcd8198956e96a74bd2a5..817582a877fa9e8fb2d48c0d7fb7e8feb989f0d8 100644 (file)
@@ -33,7 +33,6 @@ fn h(_x: &Foo) -> &int { //~ ERROR missing lifetime specifier
 
 fn i(_x: int) -> &int { //~ ERROR missing lifetime specifier
 //~^ HELP this function's return type contains a borrowed value
-//~^^ HELP consider giving it a 'static lifetime
     panic!()
 }
 
index 1a4a87e608b6fe5fdd3e88409cb0b58e56667280..9e5f15c2721961797f1de9864751670fcda937f9 100644 (file)
@@ -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"]
index 8d4ecde692d72358ead90e3ad5cf25d8cd18b38d..b73c3fa26105081355f4f5027eec7df989dbc76f 100644 (file)
@@ -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 (file)
index 0000000..56f71c8
--- /dev/null
@@ -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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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/recursion_limit.rs b/src/test/compile-fail/recursion_limit.rs
new file mode 100644 (file)
index 0000000..17afb16
--- /dev/null
@@ -0,0 +1,51 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that the recursion limit can be changed. In this case, we have
+// deeply nested types that will fail the `Send` check by overflow
+// when the recursion limit is set very low.
+
+#![feature(macro_rules)]
+#![allow(dead_code)]
+#![recursion_limit="10"]
+
+macro_rules! link {
+    ($id:ident, $t:ty) => {
+        enum $id { $id($t) }
+    }
+}
+
+link!(A,B)
+link!(B,C)
+link!(C,D)
+link!(D,E)
+link!(E,F)
+link!(F,G)
+link!(G,H)
+link!(H,I)
+link!(I,J)
+link!(J,K)
+link!(K,L)
+link!(L,M)
+link!(M,N)
+
+enum N { N(uint) }
+
+fn is_send<T:Send>() { }
+
+fn main() {
+    is_send::<A>();
+    //~^ ERROR overflow evaluating
+    //~^^ NOTE consider adding a `#![recursion_limit="20"]` attribute to your crate
+    //~^^^ NOTE must be implemented
+    //~^^^^ ERROR overflow evaluating
+    //~^^^^^ NOTE consider adding a `#![recursion_limit="20"]` attribute to your crate
+    //~^^^^^^ NOTE must be implemented
+}
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 (file)
index 1d1b244..0000000
+++ /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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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 (file)
index f68eb64..0000000
+++ /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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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() { }
index 6f875efdef7eab13715525a710ed1ac8759f39c1..308b33f9b4db195d381cff13eb8192cdd8793c83 100644 (file)
@@ -44,9 +44,9 @@ fn test<'a,'b>() {
     eq::< for<'a,'b> Foo<(&'a int,&'b uint),uint>,
           Foo(&int,&uint) -> uint                             >();
 
-    // FIXME(#18992) Test lifetime elision in `()` form:
-    // eq::< for<'a,'b> Foo<(&'a int,), &'a int>,
-    //      Foo(&int) -> &int                                   >();
+    // lifetime elision
+    eq::< for<'a,'b> Foo<(&'a int,), &'a int>,
+          Foo(&int) -> &int                                   >();
 
     // Errors expected:
     eq::< Foo<(),()>,                   Foo(char)                     >();
diff --git a/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs b/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs
new file mode 100644 (file)
index 0000000..e08d849
--- /dev/null
@@ -0,0 +1,34 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that the unboxed closure sugar can be used with an arbitrary
+// struct type and that it is equivalent to the same syntax using
+// angle brackets. This test covers only simple types and in
+// particular doesn't test bound regions.
+
+#![feature(unboxed_closures)]
+#![allow(dead_code)]
+
+trait Foo<T,U> {
+    fn dummy(&self, t: T, u: U);
+}
+
+trait Eq<Sized? X> for Sized? { }
+impl<Sized? X> Eq<X> for X { }
+fn eq<Sized? A,Sized? B:Eq<A>>() { }
+
+fn main() {
+    eq::< for<'a> Foo<(&'a int,), &'a int>,
+          Foo(&int) -> &int                                   >();
+    eq::< for<'a> Foo<(&'a int,), (&'a int, &'a int)>,
+          Foo(&int) -> (&int, &int)                           >();
+
+    let _: Foo(&int, &uint) -> &uint; //~ ERROR missing lifetime specifier
+}
index c60a99ca0dfc0eea187f1c46e08fd971c0750d83..b3528f7abe71927f0c8284dae48340f0d1347bb6 100644 (file)
@@ -14,6 +14,6 @@
 
 pub fn main() {
     let mut f = |&mut: x: int, y: int| -> int { x + y };
-    let z = f.call_mut((1u, 2));    //~ ERROR not implemented
+    let z = f.call_mut((1u, 2));    //~ ERROR type mismatch
     println!("{}", z);
 }
index 5a22490b6d6168cd280816954de0803a0ba03031..a96bde7cca4cdcb06ce12c1140709b7b9aa22e32 100644 (file)
@@ -18,7 +18,7 @@ fn call_it<F:FnMut<(int,int),int>>(y: int, mut f: F) -> int {
 
 pub fn main() {
     let f = |&mut: x: uint, y: int| -> int { (x as int) + y };
-    let z = call_it(3, f);  //~ ERROR not implemented
+    let z = call_it(3, f);  //~ ERROR type mismatch
     println!("{}", z);
 }
 
index fec1d1b27890169332757ba658a47f7ec105dca0..b0a0142f6dd556eb2de16434a6e3d02501e20c79 100644 (file)
 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
 }
index 7ceac0e7ceac6da695605fdd302fe4f2b9d432dd..4c0c82efea35d33873f78142ac1c2aaccc2e2e37 100644 (file)
@@ -147,3 +147,6 @@ fn main() {
 }
 
 fn zzz() {()}
+
+impl<T:Copy> Copy for Struct<T> {}
+
index d86aa54f451eeb87821ecc666bf9441a9d72a201..8cb8fae75cf062bbd9819228ee838ece8bf95c1e 100644 (file)
@@ -148,3 +148,6 @@ fn main() {
 }
 
 fn zzz() {()}
+
+impl Copy for Enum {}
+
index 2455c7aa5198392366b7df9cbbfffe251c5227f3..d4244ee27d4c20b696d5d09c4d22be690ef2bbcd 100644 (file)
@@ -147,3 +147,6 @@ fn main() {
 }
 
 fn zzz() {()}
+
+impl<T:Copy> Copy for Struct<T> {}
+
index 5e47d32e37673a0ed0c1596c683461f97b3d4c03..ca00587ba445d81ca4e797b2532f06f79eca204c 100644 (file)
@@ -146,3 +146,6 @@ fn main() {
 }
 
 fn zzz() {()}
+
+impl Copy for Struct {}
+
index 4d5f53fc120db6a7f8e94f29e1e6b8ad508f1ed7..e70f86a53679ea555b34b6110a0204fe7102eee4 100644 (file)
@@ -152,3 +152,6 @@ fn main() {
 }
 
 fn zzz() {()}
+
+impl Copy for Struct {}
+
index fb3bede37fd4c361a85480ff6eadce50d7a7b7c4..31bdd20e409db8eb2d8e6027142b9bb32d922934 100644 (file)
@@ -144,3 +144,6 @@ fn main() {
 }
 
 fn zzz() {()}
+
+impl Copy for TupleStruct {}
+
index 287813a959fd0554f0d1ec06114f29c101b700cf..87fdb2c42c8f86956905346f0946c1b1af4170a7 100644 (file)
@@ -148,3 +148,6 @@ fn main() {
 }
 
 fn zzz() {()}
+
+impl Copy for Struct {}
+
index bfb8abc9f6652a0a315d722b2ab99ce07d0969c8..6f488230521eb066d4e423b0c0a9ff7ac33f81e4 100644 (file)
@@ -149,3 +149,6 @@ fn main() {
 }
 
 fn zzz() {()}
+
+impl Copy for Struct {}
+
index 92a3d358f5c74062428af2aa19c2e7b5c0d57632..761d0f0be8f583309d5a682b6ddfdbb264693438 100644 (file)
 // gdb-command:print *owned
 // gdb-check:$5 = 6
 
+// gdb-command:continue
+
+// gdb-command:print variable
+// gdb-check:$6 = 2
+// gdb-command:print constant
+// gdb-check:$7 = 2
+// gdb-command:print a_struct
+// gdb-check:$8 = {a = -3, b = 4.5, c = 5}
+// gdb-command:print *struct_ref
+// gdb-check:$9 = {a = -3, b = 4.5, c = 5}
+// gdb-command:print *owned
+// gdb-check:$10 = 6
+
 
 // === LLDB TESTS ==================================================================================
 
 // lldb-command:print *owned
 // lldb-check:[...]$4 = 6
 
+// lldb-command:continue
+
+// lldb-command:print variable
+// lldb-check:[...]$5 = 2
+// lldb-command:print constant
+// lldb-check:[...]$6 = 2
+// lldb-command:print a_struct
+// lldb-check:[...]$7 = Struct { a: -3, b: 4.5, c: 5 }
+// lldb-command:print *struct_ref
+// lldb-check:[...]$8 = Struct { a: -3, b: 4.5, c: 5 }
+// lldb-command:print *owned
+// lldb-check:[...]$9 = 6
+
+#![feature(unboxed_closures)]
 #![allow(unused_variables)]
 
 struct Struct {
@@ -65,12 +92,22 @@ fn main() {
     let struct_ref = &a_struct;
     let owned = box 6;
 
-    let closure = || {
-        zzz(); // #break
-        variable = constant + a_struct.a + struct_ref.a + *owned;
-    };
-
-    closure();
+    {
+        let closure = || {
+            zzz(); // #break
+            variable = constant + a_struct.a + struct_ref.a + *owned;
+        };
+
+        closure();
+    }
+
+    {
+        let mut unboxed_closure = |&mut:| {
+            zzz(); // #break
+            variable = constant + a_struct.a + struct_ref.a + *owned;
+        };
+        unboxed_closure();
+    }
 }
 
 fn zzz() {()}
index 1b1765475f3386d110f793bd652ea66c12579b65..db01bc94e32b81fe65ceb1d259d3bb310620cc94 100644 (file)
@@ -21,6 +21,8 @@
 
 struct S { eax: int }
 
+impl Copy for S {}
+
 fn test3() {
     let regs = &Cell::new(S {eax: 0});
     match true { true => { } _ => { } }
index 8d8daed1393c7f21a2edaa752f1cc13285e0d179..12d961bd59ebfce516a701ca53e19de16546ef9d 100644 (file)
@@ -16,6 +16,8 @@ struct Foo {
     c: i8
 }
 
+impl Copy for Foo {}
+
 #[link(name = "test", kind = "static")]
 extern {
     fn foo(f: Foo) -> Foo;
index eeddd5e19a841b497c245879f89d71787c5a8dca..cab98204b17d76ddeb02de086840b877a39f8f70 100644 (file)
@@ -11,6 +11,9 @@
 #![feature(lang_items)]
 #![no_std]
 
+#[lang="copy"]
+trait Copy { }
+
 #[lang="sized"]
 trait Sized { }
 
index 270e6ad785c2531cd20b7197a9fbabebf3e32a8e..cd79a95dace7afcef69ac94f66e180f2218617d6 100644 (file)
@@ -11,7 +11,6 @@
 // aux-build:issue-13560-1.rs
 // aux-build:issue-13560-2.rs
 // aux-build:issue-13560-3.rs
-// ignore-pretty FIXME #19501
 // ignore-stage1
 
 // Regression test for issue #13560, the test itself is all in the dependent
index 3d191f6c4b469b6b766459cb2d4d4df509dc1ac2..df4106c98446c4344ba05945833721d4923ce964 100644 (file)
@@ -15,6 +15,8 @@ enum newtype {
     newvar(int)
 }
 
+impl Copy for newtype {}
+
 pub fn main() {
 
     // Test that borrowck treats enums with a single variant
index 683e7ece8717d714d0b3704094d06d91ab6a19b2..382caa83c61c71cb1b4acac82aab30c0c8d15ca8 100644 (file)
 
 struct X<T>(T);
 
-impl <T:Sync> RequiresShare for X<T> { }
+impl<T:Copy> Copy for X<T> {}
 
-impl <T:Sync+Send> RequiresRequiresShareAndSend for X<T> { }
+impl<T:Sync> RequiresShare for X<T> { }
 
-impl <T:Copy> RequiresCopy for X<T> { }
+impl<T:Sync+Send> RequiresRequiresShareAndSend for X<T> { }
+
+impl<T:Copy> RequiresCopy for X<T> { }
 
 pub fn main() { }
index c7c655b3db48c444f2a9abbe6b1dcfc194095af5..6455f1e4bb2b96e68314ad32ee6be3eb45422213 100644 (file)
@@ -24,6 +24,8 @@ fn clone(&self) -> Foo {
     }
 }
 
+impl Copy for Foo {}
+
 pub fn main() {
     let x = Cell::new(Foo { x: 22 });
     let _y = x.get();
index a0d35fd596b535c07f8cf10ee789f6e352d17445..2a9756d7714cdd508769bcbc749ba5dfdc7bae7a 100644 (file)
@@ -14,6 +14,8 @@
 #[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)
index 51cd62677ca1ca9a68af0ac48bfb4628008ee6d2..df0012e07ec72ede9248e4d04d8e1602ced66979 100644 (file)
@@ -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
index faec0c502808c97028a086c128aeb60e3e2e0ec8..e0d9d569d175ddac43baa1183b0152078c485c37 100644 (file)
@@ -28,6 +28,8 @@ struct MyType {
     dummy: uint
 }
 
+impl Copy for MyType {}
+
 impl MyTrait for MyType {
     fn get(&self) -> MyType { (*self).clone() }
 }
index fe171a9f73dc781d10cfb3a69441f9c2208b05fa..9a1a5de936005a01357432f7ce5b9cef56fbe5e9 100644 (file)
@@ -12,6 +12,8 @@ enum Foo {
     Bar = 0xDEADBEE
 }
 
+impl Copy for Foo {}
+
 static X: Foo = Foo::Bar;
 
 pub fn main() {
index 04fe6d5cefdc39b8d55382fcaca928bc43e2f4b8..26cb27cc653925b576e27eb874eb2dc9f28242ed 100644 (file)
@@ -33,6 +33,8 @@ fn foo2<T:ToBar>(x: &Fat<[T]>) {
 #[deriving(PartialEq,Eq)]
 struct Bar;
 
+impl Copy for Bar {}
+
 trait ToBar {
     fn to_bar(&self) -> Bar;
 }
index 6b8e25e85590f6aaa2d57bbcf84e306885f9465e..bf5b300f7cf0aa72be0b5337fc8ff5de6187bb3b 100644 (file)
@@ -49,6 +49,8 @@ fn foo3(x: &Fat<Fat<[int]>>) {
 #[deriving(PartialEq,Eq)]
 struct Bar;
 
+impl Copy for Bar {}
+
 trait ToBar {
     fn to_bar(&self) -> Bar;
 }
index 976273095510402e0fa93ba56c80041990b11a7f..907c7810736ba98f2291fca3f316d86fd53a501b 100644 (file)
@@ -17,11 +17,15 @@ struct Fat<Sized? T> {
 #[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;
index 6b780d854599e54880d1692b4f2177136e747e34..e5d11ac1adb2aeebfe2863c9be7701c1c20af482 100644 (file)
@@ -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)
index deb3f6b6c7c3edfebdbf4d1d56f8b88819fcb0ec..cf8e742947d1da7ff299c78f3cb1d12e4d1e3a14 100644 (file)
@@ -20,6 +20,7 @@ enum E {
                 A = 0
             }
             static C: E = E::V;
+            impl Copy for E {}
             pub fn check() {
                 assert_eq!(size_of::<E>(), size_of::<$t>());
                 assert_eq!(E::V as $t, $v as $t);
index 829870930a4564945684ec442f3c5ea968bd7d6a..eeda299c71fa6105234824ee21325b7765a3408d 100644 (file)
 
 struct LM { resize_at: uint, size: uint }
 
+impl Copy for LM {}
+
 enum HashMap<K,V> {
     HashMap_(LM)
 }
 
+impl<K,V> Copy for HashMap<K,V> {}
+
 fn linear_map<K,V>() -> HashMap<K,V> {
     HashMap::HashMap_(LM{
         resize_at: 32,
index 3fc5310a29bc783ffe467e3f3a241e19197dbd74..48e9d9dea22cdae0e3ee69cb0c9ac7f5addbf011 100644 (file)
@@ -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)
index 4a45ce660585f70d87e7c8b3d6e0b96870e22e92..6e9ba4f8f41f1b2ab0bbe3c31df589d48866de5e 100644 (file)
@@ -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);
index 758d726851d078e1fba31a5074d482ae59a14c8f..c95ca3fff8c564eae1e8fa8426b8bf95b34c2df5 100644 (file)
@@ -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)
index ea96005dc602e8434a442571c53e2ce2178d392d..83101a3d2cc3a2130e3e5364aaeb1fc59d9858dc 100644 (file)
@@ -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)
index e95c2034131552beed85a747b442bbac4233dfa2..2ca5f430a2a37e2c58a740761baffc30ed9a8079 100644 (file)
@@ -13,6 +13,8 @@
 
 struct Point {x: int, y: int, z: int}
 
+impl Copy for Point {}
+
 fn f(p: &Cell<Point>) {
     assert!((p.get().z == 12));
     p.set(Point {x: 10, y: 11, z: 13});
index 6161d31c4a9ea00f5ce2839c7b8ffb7edeb9272c..2b80a4040362612364a4bf090f3b91d57c4f80b8 100644 (file)
@@ -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;
index 3e6b6502074476c9d1e087f83e058728c5869033..be4998c86fddfe3e82ce41ce5e6d293110d2e3e9 100644 (file)
@@ -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;
index 5ad1e89425b0905f01ce2dca7a56a15f599e3047..e8d91815bf9d73c8b4ef75ed8b78cc539d45bbf3 100644 (file)
@@ -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;
index 14ba7c80059b5755f16843eeb11d4bd11490cff3..7aa710df80058af2a0e5780d76d48ca1565804e9 100644 (file)
@@ -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;
index 6a26ec44312d7abe2bbc140cb60039a6f8aba79f..5d6815fc3c7a49b76440f979cb099ac4e9d7c3f2 100644 (file)
@@ -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;
index 89f342b4ee5edfdb9aa6a247e3f78d063035de7e..a341bfe22eb918a3d7575693c6b2a5d723193d73 100644 (file)
@@ -14,6 +14,8 @@
 
 struct Triple {x: int, y: int, z: int}
 
+impl Copy for Triple {}
+
 pub fn main() {
     let mut x = 62;
     let mut y = 63;
index c7f3c9d718221c7c5126c427c57ccd4acdce0668..b1bc40b662de1f6a0e135fe43133dab8739d75a2 100644 (file)
@@ -10,6 +10,8 @@
 
 enum Q { R(Option<uint>) }
 
+impl Copy for Q {}
+
 fn xyzzy(q: Q) -> uint {
     match q {
         Q::R(S) if S.is_some() => { 0 }
index 5bfbe4bf5a01da6b1d018ff7ceea0cafd79d0c91..0157423863c2aa595a831eb5f74b29560efbd037 100644 (file)
@@ -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 } };
index 4496a921e24485c6d7662b012c24c9a44f2477b0..1caa04ae0b16d2af0da3f3c14951519bf37fe4a6 100644 (file)
@@ -20,6 +20,8 @@ struct XYZ {
     z: int
 }
 
+impl Copy for XYZ {}
+
 fn main() {
     let mut connected = HashSet::new();
     let mut border = HashSet::new();
index 7958b9ec117cbea071278b4369c1b144f190e728..35bd68d803a2e3d43edef6382ef20b35f6cf324e 100644 (file)
@@ -8,18 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[deriving(PartialEq, PartialOrd)]
+#[deriving(Eq, PartialEq, PartialOrd, Ord)]
 enum Test<'a> {
     Int(&'a int),
     Slice(&'a [u8]),
 }
 
-#[deriving(PartialEq, PartialOrd)]
+#[deriving(Eq, PartialEq, PartialOrd, Ord)]
 struct Version {
     vendor_info: &'static str
 }
 
-#[deriving(PartialEq, PartialOrd)]
+#[deriving(Eq, PartialEq, PartialOrd, Ord)]
 struct Foo(&'static str);
 
 fn main() {}
index cee5c808f9982c9f2abffb676db472df666c8f89..0ebd3ae8d97693294e350f84c3c585da43f17d9d 100644 (file)
@@ -13,6 +13,8 @@ enum Foo {
     Baz
 }
 
+impl Copy for Foo {}
+
 impl Foo {
     fn foo(&self) {
         match self {
index 85dd879c830ce564763381579b9a6ce650051102..1f371f0a1c204c8f22212f0026fbda5106f64100 100644 (file)
 trait clam<A> {
   fn chowder(&self, y: A);
 }
+
 struct foo<A> {
   x: A,
 }
 
+impl<A:Copy> Copy for foo<A> {}
+
 impl<A> clam<A> for foo<A> {
   fn chowder(&self, _y: A) {
   }
index a9ebfbcbf3322855036626d69e1da7f883b4c99a..bc014f699c731f15965679bdc2ae895e58a07d98 100644 (file)
@@ -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)();
index d0e995da5f130563c713ada525e311c4d41cd81d..9e9d611f1a320eb994688c45e8a4ab858322782e 100644 (file)
@@ -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<meal>, cond: bool) {
     match *m {
       meal::to_go(_) => { }
index 4e330b9a0e7dd98ec2b0e76f49dd001993a7b778..d04d8f92ac40d62dbc1783e05b4a4bc21ef2fd31 100644 (file)
@@ -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,
index bebaad2d297c73bdec020542254b8083793fa76a..ada3e37c092a7a92d28bb4c43126ad21099c66b8 100644 (file)
@@ -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)]
index 9fbabed3a94dddc88d6d23b4db6981235db764ad..de6926e551296629acee1e0f522db302aaefc104 100644 (file)
@@ -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 {
index 73bf375923a74061175250eb79d5cb2ce76cc593..0a13e001fabf5895f91d217e21d2f487913a11ea 100644 (file)
 */
 
 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);
index 982d4f6a0b56d242f7107c7374e4ff1ae3cb2260..81774c73c392c914a7eaa893887a9f2044f28d1b 100644 (file)
@@ -13,6 +13,7 @@
 // ignore-windows #13361
 
 #![no_std]
+#![feature(lang_items)]
 
 extern crate "lang-item-public" as lang_lib;
 
index 85fa61266a338fdd5d183cf2a930de49e5881794..400aab64b4cdb4460a5f8e68a1650f1ab66ca8f8 100644 (file)
@@ -38,6 +38,8 @@ enum EnumWithStructVariants {
 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);
index b821c064cacfe25f21af897f0c11babb2a82ebfb..36dfe83a9ebae13080e0eaebbc2b7f7da3da59e1 100644 (file)
@@ -14,6 +14,8 @@
 
 struct Foo;
 
+impl Copy for Foo {}
+
 trait Bar {
     fn foo1(&self);
     fn foo2(self);
index 3d73f34f8cfd6edcb182af1e5ed14fd09b3ac431..788a25efcf9872a8c7b0fe1757ac640ae8f5e222 100644 (file)
@@ -14,6 +14,8 @@
 
 struct Foo;
 
+impl Copy for Foo {}
+
 impl Foo {
     fn foo(self, x: &Foo) {
         unsafe { COUNT *= 2; }
index 2233a5c3ea77456c10dea61dd062855b390678f5..f5b51cd423301175c94e6b0102b72bd87c1aab13 100644 (file)
  */
 
 struct S<T> { i:u8, t:T }
-impl<T> S<T> { fn unwrap(self) -> T { self.t } }
+
+impl<T:Copy> Copy for S<T> {}
+
+impl<T> S<T> {
+    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<A> = S { i: 0, t: A((13, 104)) };
     static Cb: S<B> = S { i: 0, t: B(31337) };
index 76c87f5d4c59f4763fec8d1d5d7c52a3d21f3e8d..87d188418bdd3ee353dfe487b6bb97e238924eef 100644 (file)
@@ -18,6 +18,8 @@ struct MyType {
     dummy: uint
 }
 
+impl Copy for MyType {}
+
 impl MyTrait<uint> for MyType {
     fn get(&self) -> uint { self.dummy }
 }
index 13131be93c892b61ed5ab6ae77314358d89af884..1aa15cc5983491a023195e2b0e66da9b65fa1bb9 100644 (file)
@@ -27,6 +27,8 @@ struct MyType {
     dummy: uint
 }
 
+impl Copy for MyType {}
+
 impl MyTrait<uint> for MyType {
     fn get(&self) -> uint { self.dummy }
 }
index 0d1103086ae790729bc45caba8d8d678b1b8c7c2..093fd6c81cc637a3a13c049307381cc1a2f2feca 100644 (file)
 
 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/opt-out-copy.rs b/src/test/run-pass/opt-out-copy.rs
new file mode 100644 (file)
index 0000000..8c7072c
--- /dev/null
@@ -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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<T:Copy>() { }
+
+fn main() {
+    is_copy::<CantCopyThis>();
+    is_copy::<CantCopyThisEither>();
+    is_copy::<IWantToCopyThis>();
+    is_copy::<IWantToCopyThisToo>();
+}
+
index 2a44df7a1b5667770c167662348ff0524779b2db..5f399deb885302aa8d3a05b87bfa917951941cd1 100644 (file)
@@ -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;
index 0a9ac734c26fdd96a5f6d06e61503ed9459def91..f0daf371ca79e90d791b99ce4f25caa7ce6020c5 100644 (file)
@@ -15,6 +15,8 @@ struct DerefWrapper<X, Y> {
     y: Y
 }
 
+impl<X:Copy,Y:Copy> Copy for DerefWrapper<X,Y> {}
+
 impl<X, Y> DerefWrapper<X, Y> {
     fn get_x(self) -> X {
         self.x
@@ -33,6 +35,8 @@ pub struct DerefWrapperHideX<X, Y> {
         pub y: Y
     }
 
+    impl<X:Copy,Y:Copy> Copy for DerefWrapperHideX<X,Y> {}
+
     impl<X, Y> DerefWrapperHideX<X, Y> {
         pub fn new(x: X, y: Y) -> DerefWrapperHideX<X, Y> {
             DerefWrapperHideX {
index c20e62351a618ef3ce2d781e0060184cbf9f61cc..59bb5678b6936e5a490a2a0b48a027c78f4bd29f 100644 (file)
@@ -19,6 +19,8 @@ struct Foo {
     baz: u64
 }
 
+impl Copy for Foo {}
+
 pub fn main() {
     let foos = [Foo { bar: 1, baz: 2 }, .. 10];
 
index 0dc547f1a027e5935d3121ef9ef44e42d1da7c39..8adad012ec69b2e51cb392928be26e9c6772a8bf 100644 (file)
@@ -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; }
index b9b5cfebb0b56785a6c33ff241a754802615b20e..02fcf1ad0689ed6996a753a6b2cca42f6f01dd26 100644 (file)
@@ -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);
index f074ca9a8892104175c3f39e2f193f0fd34446c5..79f8ca48882cfb4a8881b75ed9b64e69023461c4 100644 (file)
@@ -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
index c011d11749b60318f4bd859881bce3300813fd6c..5b4169a4e84624b56253c881f9dfa463fcbd317b 100644 (file)
@@ -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
index 58de2e0e20e0c857c43ece6968f689de518818b3..73eb7ca71882cece3aa3b81ae22c9f9ea37ef19a 100644 (file)
@@ -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
index 708664f33e930697b320544f085f88f5a14dff9d..622f820971ffb03863982c45d29e331dbe4ee6af 100644 (file)
@@ -19,6 +19,8 @@ struct Box<T> {
     t: T
 }
 
+impl<T:Copy> Copy for Box<T> {}
+
 impl<T:Clone> Get<T> for Box<T> {
     fn get(&self) -> T {
         self.t.clone()
diff --git a/src/test/run-pass/regions-link-fn-args.rs b/src/test/run-pass/regions-link-fn-args.rs
new file mode 100644 (file)
index 0000000..2823622
--- /dev/null
@@ -0,0 +1,22 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that region inference correctly links up the regions when a
+// `ref` borrow occurs inside a fn argument.
+
+#![allow(dead_code)]
+
+fn with<'a>(_: |&'a Vec<int>| -> &'a Vec<int>) { }
+
+fn foo() {
+    with(|&ref ints| ints);
+}
+
+fn main() { }
index e13edae330ae7ae8a227b709b519c144de9ebf5d..e10c12a603729f94feaeedff384c21f136a2a396 100644 (file)
@@ -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>
 {
index f2482474073e027ca44bd8502f72a88830412ab5..1603f7f9763fb037ef4fc8ff18b0fa0fb20c44fc 100644 (file)
@@ -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 (file)
index 930364c..0000000
+++ /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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<Span>),
-}
-
-#[deriving(Clone, Show)]
-struct Span {
-    lo: uint,
-    hi: uint,
-    expanded_from: opt_span,
-}
-
-#[deriving(Clone, Show)]
-struct Spanned<T> {
-    data: T,
-    span: Span,
-}
-
-type ty_ = uint;
-
-#[deriving(Clone, Show)]
-struct Path_ {
-    global: bool,
-    idents: Vec<String> ,
-    types: Vec<Box<ty>>,
-}
-
-type path = Spanned<Path_>;
-type ty = Spanned<ty_>;
-
-#[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<ty> = 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());
-}
index 68c210b018ab977c5e15005db68729359b63488c..31c29b615fc0938474c3bf836338f6f659ce1ad8 100644 (file)
@@ -15,6 +15,8 @@
 
 #[simd] struct f32x4(f32, f32, f32, f32);
 
+impl Copy for f32x4 {}
+
 fn add<T: ops::Add<T, T>>(lhs: T, rhs: T) -> T {
     lhs + rhs
 }
index 17d647e58b5e2d22fb88c43bd514ea473315f461..de38a553e123f1b49b8798653ad82f28d6ce7c9f 100644 (file)
 
 #[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;
 
index 63574316fe57398d5790d5e761178a1bdfe92e91..bb06aec23f6bcf8e6b52de2a3861eaeabe2fc775 100644 (file)
 // 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};
 
index 88f72932ca0577fb415330e762415c5d93b72dc2..d0446d83d2e013f85bce953af6ec85eb05213169 100644 (file)
@@ -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)
index 7aa2ba280acaf1fb81958ae26fdde137ce9a435f..cf53c1a912a54082c65673cda989dbe0d5ce962b 100644 (file)
@@ -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)
index 1e241ad22784e2df6db474542864efc52491ba94..7d924f977cbef33f9a726572bd86a73508a98979 100644 (file)
@@ -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);
index 55beebbf2bc576534000f91008729a1d0bb6af9a..37d69ddfe07660a97e42c2c55ab54a76408a32de 100644 (file)
@@ -19,6 +19,8 @@ struct Struct {
     y: int,
 }
 
+impl Copy for Struct {}
+
 impl Trait for Struct {
     fn f(&self) {
         println!("Hi!");
index a5547c0eea98bfb741fb191fbc550e6db62a023f..6b00a8b5c2d9fab720eed3442e3ae763bf6fd88c 100644 (file)
@@ -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 @@ fn isEq(a: &Color, b: &Color) -> bool {
     }
 }
 
+#[deriving(Clone)]
 enum ColorTree {
     leaf(Color),
     branch(Box<ColorTree>, Box<ColorTree>)
@@ -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 }
         }
index 21b9c774e8c4306516b4cfaa94ab4c5db9229fc1..e4b7d2eb60bd33d8d502ea9319f3e1413d854714 100644 (file)
@@ -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 @@ fn isEq(&self, a: &Color) -> bool {
     }
 }
 
+#[deriving(Clone)]
 enum ColorTree {
     leaf(Color),
     branch(Box<ColorTree>, Box<ColorTree>)
@@ -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 }
         }
index b96820eee14b77c9c70f37f351e4deeeb1cdf163..b6b9fb67f90538a323d9537a1216eca11fb3f9c4 100644 (file)
@@ -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<T> {
     f: T,
 }
 
+impl<T:Copy> Copy for Bar<T> {}
+
 impl<T> Bar<T> {
     fn foo(self: Bar<T>, x: int) -> int {
         x
diff --git a/src/test/run-pass/ufcs-type-params.rs b/src/test/run-pass/ufcs-type-params.rs
new file mode 100644 (file)
index 0000000..ccd5a22
--- /dev/null
@@ -0,0 +1,22 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait Foo<T> {
+    fn get(&self) -> T;
+}
+
+impl Foo<i32> for i32 {
+    fn get(&self) -> i32 { *self }
+}
+
+fn main() {
+    let x: i32 = 1;
+    Foo::<i32>::get(&x);
+}
index 43fb4b296ccb94ea482011f81b905584a7a12d37..cd97fd96fa3bbd963d1dfed4294a5503aeeafb72 100644 (file)
@@ -30,6 +30,9 @@ fn bar<'a, T:'a> (t: T) -> Box<FnOnce<(),T> + 'a> {
 
     #[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);
index f482b2e1e703bbd582806f596747d6a9928e4937..577e114945c66ee33ed254b9a39c3ee681a07933 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-test
-
 extern crate libc;
 
 use std::io::process::Command;
 use libc::funcs::posix88::unistd;
 
 
-// "ps -A -o pid,sid,command" with GNU ps should output something like this:
-//   PID   SID COMMAND
-//     1     1 /sbin/init
+// The output from "ps -A -o pid,ppid,args" should look like this:
+//   PID  PPID COMMAND
+//     1     0 /sbin/init
 //     2     0 [kthreadd]
-//     3     0 [ksoftirqd/0]
 // ...
-// 12562  9237 ./spawn-failure
-// 12563  9237 [spawn-failure] <defunct>
-// 12564  9237 [spawn-failure] <defunct>
+//  6076  9064 /bin/zsh
+// ...
+//  7164  6076 ./spawn-failure
+//  7165  7164 [spawn-failure] <defunct>
+//  7166  7164 [spawn-failure] <defunct>
 // ...
-// 12592  9237 [spawn-failure] <defunct>
-// 12593  9237 ps -A -o pid,sid,command
-// 12884 12884 /bin/zsh
-// 12922 12922 /bin/zsh
+//  7197  7164 [spawn-failure] <defunct>
+//  7198  7164 ps -A -o pid,ppid,command
 // ...
 
 #[cfg(unix)]
 fn find_zombies() {
-    // http://man.freebsd.org/ps(1)
-    // http://man7.org/linux/man-pages/man1/ps.1.html
-    #[cfg(not(target_os = "macos"))]
-    const FIELDS: &'static str = "pid,sid,command";
-
-    // https://developer.apple.com/library/mac/documentation/Darwin/
-    // Reference/ManPages/man1/ps.1.html
-    #[cfg(target_os = "macos")]
-    const FIELDS: &'static str = "pid,sess,command";
-
-    let my_sid = unsafe { unistd::getsid(0) };
+    let my_pid = unsafe { unistd::getpid() };
 
-    let ps_cmd_output = Command::new("ps").args(&["-A", "-o", FIELDS]).output().unwrap();
+    // http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html
+    let ps_cmd_output = Command::new("ps").args(&["-A", "-o", "pid,ppid,args"]).output().unwrap();
     let ps_output = String::from_utf8_lossy(ps_cmd_output.output.as_slice());
 
-    let found = ps_output.split('\n').enumerate().any(|(line_no, line)|
-        0 < line_no && 0 < line.len() &&
-        my_sid == from_str(line.split(' ').filter(|w| 0 < w.len()).nth(1)
-            .expect("1st column should be Session ID")
-            ).expect("Session ID string into integer") &&
-        line.contains("defunct") && {
-            println!("Zombie child {}", line);
-            true
+    for (line_no, line) in ps_output.split('\n').enumerate() {
+        if 0 < line_no && 0 < line.len() &&
+           my_pid == from_str(line.split(' ').filter(|w| 0 < w.len()).nth(1)
+               .expect("1st column should be PPID")
+               ).expect("PPID string into integer") &&
+           line.contains("defunct") {
+            panic!("Zombie child {}", line);
         }
-    );
-
-    assert!( ! found, "Found at least one zombie child");
+    }
 }
 
 #[cfg(windows)]
@@ -71,10 +56,13 @@ fn find_zombies() { }
 fn main() {
     let too_long = format!("/NoSuchCommand{:0300}", 0u8);
 
-    for _ in range(0u32, 100) {
-        let invalid = Command::new(too_long.as_slice()).spawn();
-        assert!(invalid.is_err());
-    }
+    let _failures = Vec::from_fn(100, |_i| {
+        let cmd = Command::new(too_long.as_slice());
+        let failed = cmd.spawn();
+        assert!(failed.is_err(), "Make sure the command fails to spawn(): {}", cmd);
+        failed
+    });
 
     find_zombies();
+    // then _failures goes out of scope
 }