]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #19628 : jbranchaud/rust/add-string-as-string-doctest, r=steveklabnik
authorbors <bors@rust-lang.org>
Wed, 10 Dec 2014 06:46:16 +0000 (06:46 +0000)
committerbors <bors@rust-lang.org>
Wed, 10 Dec 2014 06:46:16 +0000 (06:46 +0000)
402 files changed:
mk/dist.mk
src/README.md [deleted file]
src/compiletest/common.rs
src/compiletest/compiletest.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-testing.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/arc.rs
src/liballoc/boxed.rs
src/liballoc/rc.rs
src/libarena/lib.rs
src/libcollections/binary_heap.rs
src/libcollections/bit.rs
src/libcollections/btree/map.rs
src/libcollections/btree/node.rs
src/libcollections/btree/set.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/libcollections/tree/map.rs
src/libcollections/tree/set.rs
src/libcollections/trie/map.rs
src/libcollections/trie/set.rs
src/libcollections/vec.rs
src/libcollections/vec_map.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/libcoretest/cell.rs
src/libcoretest/char.rs
src/libcoretest/fmt/num.rs
src/libcoretest/option.rs
src/libcoretest/result.rs
src/libcoretest/tuple.rs
src/libflate/lib.rs
src/libfmt_macros/lib.rs
src/libgetopts/lib.rs
src/libgraphviz/lib.rs
src/liblibc/lib.rs
src/liblog/directive.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/test/tests.rs
src/libregex/vm.rs
src/libregex_macros/lib.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/fragments.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/graphviz.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/dead.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/session/mod.rs
src/librustc/util/common.rs
src/librustc/util/nodemap.rs
src/librustc/util/ppaux.rs
src/librustc_back/arm.rs
src/librustc_back/rpath.rs
src/librustc_back/sha2.rs
src/librustc_back/target/mod.rs
src/librustc_driver/driver.rs
src/librustc_driver/lib.rs
src/librustc_driver/pretty.rs
src/librustc_llvm/diagnostic.rs
src/librustc_llvm/lib.rs
src/librustc_trans/back/link.rs
src/librustc_trans/back/lto.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/asm.rs
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/basic_block.rs
src/librustc_trans/trans/builder.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/context.rs
src/librustc_trans/trans/datum.rs
src/librustc_trans/trans/debuginfo.rs
src/librustc_trans/trans/expr.rs
src/librustc_trans/trans/glue.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/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/doctree.rs
src/librustdoc/html/format.rs
src/librustdoc/html/item_type.rs
src/librustdoc/html/markdown.rs
src/librustdoc/html/render.rs
src/librustdoc/lib.rs
src/librustdoc/passes.rs
src/librustdoc/stability_summary.rs
src/librustdoc/test.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/map.rs
src/libstd/collections/hash/set.rs
src/libstd/collections/hash/table.rs
src/libstd/collections/lru_cache.rs
src/libstd/comm/mod.rs
src/libstd/dynamic_lib.rs
src/libstd/fmt.rs
src/libstd/io/buffered.rs
src/libstd/io/comm_adapters.rs
src/libstd/io/fs.rs
src/libstd/io/mem.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/stdio.rs
src/libstd/io/util.rs
src/libstd/num/strconv.rs
src/libstd/num/uint_macros.rs
src/libstd/os.rs
src/libstd/path/mod.rs
src/libstd/path/posix.rs
src/libstd/path/windows.rs
src/libstd/rand/mod.rs
src/libstd/rt/backtrace.rs
src/libstd/sync/future.rs
src/libstd/sync/poison.rs
src/libstd/sys/common/thread_local.rs
src/libstd/sys/unix/fs.rs
src/libstd/sys/windows/fs.rs
src/libstd/sys/windows/process.rs
src/libstd/sys/windows/tty.rs
src/libstd/task.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/format.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/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/test.rs
src/libsyntax/visit.rs
src/libterm/lib.rs
src/libterm/terminfo/mod.rs
src/libterm/terminfo/parm.rs
src/libterm/terminfo/parser/compiled.rs
src/libterm/terminfo/searcher.rs
src/libtest/lib.rs
src/libtest/stats.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/pretty/issue-4264.pp
src/test/run-fail/test-should-fail-bad-message.rs [new file with mode: 0644]
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/test-should-fail-good-message.rs [new file with mode: 0644]
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)
diff --git a/src/README.md b/src/README.md
deleted file mode 100644 (file)
index c72fd14..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-This is a preliminary version of the Rust compiler, libraries and tools.
-
-Source layout:
-
-| Path                | Description                                               |
-| ------------------- | --------------------------------------------------------- |
-| `librustc/`         | The self-hosted compiler                                  |
-| `liballoc/`         | Rust's core allocation library                            |
-| `libcore/`          | The Rust core library                                     |
-| `libdebug/`         | Debugging utilities                                       |
-| `libstd/`           | The standard library (imported and linked by default)     |
-| `libsyntax/`        | The Rust parser and pretty-printer                        |
-| `libtest/`          | Rust's test-runner code                                   |
-| ------------------- | --------------------------------------------------------- |
-| `libarena/`         | The arena (a fast but limited) memory allocator           |
-| `libbacktrace/`     | The libbacktrace library                                  |
-| `libcollections/`   | A collection of useful data structures and containers     |
-| `libflate/`         | Simple compression library                                |
-| `libfmt_macros/`    | Macro support for format strings                          |
-| `libfourcc/`        | Data format identifier library                            |
-| `libgetopts/`       | Get command-line-options library                          |
-| `libglob/`          | Unix glob patterns library                                |
-| `libgraphviz/`      | Generating files for Graphviz                             |
-| `libhexfloat/`      | Hexadecimal floating-point literals                       |
-| `liblibc/`          | Bindings for the C standard library                       |
-| `liblog/`           | Utilities for program-wide and customizable logging       |
-| `libnum/`           | Extended number support library (complex, rational, etc)  |
-| `librand/`          | Random numbers and distributions                          |
-| `libregex/`         | Regular expressions                                       |
-| `libregex_macros/`  | The regex! syntax extension                               |
-| `libsemver/`        | Rust's semantic versioning library                        |
-| `libserialize/`     | Encode-Decode types library                               |
-| `libsync/`          | Concurrency mechanisms and primitives                     |
-| `libterm/`          | ANSI color library for terminals                          |
-| `libtime/`          | Time operations library                                   |
-| `liburl/`           | URL handling lirary                                       |
-| `libuuid/`          | UUID's handling code                                      |
-| ------------------- | --------------------------------------------------------- |
-| `rt/`               | The runtime system                                        |
-| `rt/rust_*.c`       | - Some of the runtime services                            |
-| `rt/vg`             | - Valgrind headers                                        |
-| `rt/msvc`           | - MSVC support                                            |
-| `rt/sundown`        | - The Markdown library used by rustdoc                    |
-| ------------------- | --------------------------------------------------------- |
-| `compiletest/`      | The test runner                                           |
-| `test/`             | Testsuite                                                 |
-| `test/codegen`      | - Tests for the LLVM IR infrastructure                    |
-| `test/compile-fail` | - Tests that should fail to compile                       |
-| `test/debug-info`   | - Tests for the `debuginfo` tool                          |
-| `test/run-fail`     | - Tests that should compile, run and fail                 |
-| `test/run-make`     | - Tests that depend on a Makefile infrastructure          |
-| `test/run-pass`     | - Tests that should compile, run and succeed              |
-| `test/bench`        | - Benchmarks and miscellaneous                            |
-| `test/pretty`       | - Pretty-printer tests                                    |
-| `test/auxiliary`    | - Dependencies of tests                                   |
-| ------------------- | --------------------------------------------------------- |
-| `librustdoc/`       | The Rust API documentation tool                           |
-| ------------------- | --------------------------------------------------------- |
-| `llvm/`             | The LLVM submodule                                        |
-| `rustllvm/`         | LLVM support code                                         |
-| ------------------- | --------------------------------------------------------- |
-| `etc/`              | Scripts, editors support, misc                            |
-
-
-NOTE: This list (especially the second part of the table which contains modules and libraries)
-is highly volatile and subject to change.
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 e28029c4d9d23cd29532d7f8143c3f8c36ad7e23..47ab675aff9347f95e99d1e7a2ce80a31abf940d 100644 (file)
@@ -346,7 +346,7 @@ pub fn make_test(config: &Config, testfile: &Path, f: || -> test::TestFn)
         desc: test::TestDesc {
             name: make_test_name(config, testfile),
             ignore: header::is_test_ignored(config, testfile),
-            should_fail: false
+            should_fail: test::ShouldFail::No,
         },
         testfn: f(),
     }
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 a3bf810dde180f46081420ab0d21c8931d7b54df..f7cf5e5ac0019c9dd6e847625a2d8024b0e92d90 100644 (file)
@@ -89,6 +89,21 @@ fn test_out_of_bounds_failure() {
 }
 ~~~
 
+`#[should_fail]` tests can be fragile as it's hard to guarantee that the test
+didn't fail for an unexpected reason. To help with this, an optional `expected`
+parameter can be added to the `should_fail` attribute. The test harness will
+make sure that the failure message contains the provided text. A safer version
+of the example above would be:
+
+~~~test_harness
+#[test]
+#[should_fail(expected = "index out of bounds")]
+fn test_out_of_bounds_failure() {
+    let v: &[int] = &[];
+    v[0];
+}
+~~~
+
 A test runner built with the `--test` flag supports a limited set of
 arguments to control which tests are run:
 
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 ef05279e825eaad799ae0c4aea4a4114d1f47da5..1d2157b7e2fa3594ed8f36b7a36f9a11169bfadb 100644 (file)
@@ -523,7 +523,7 @@ fn test_weak_count() {
     #[test]
     fn show_arc() {
         let a = Arc::new(5u32);
-        assert!(format!("{}", a).as_slice() == "5")
+        assert!(format!("{}", a) == "5")
     }
 
     // Make sure deriving works with Arc<T>
index eb483498998c5f3beaf177d35910152347fb60df..b0ba20b0133579556417029c6e97a1ee776ebb15 100644 (file)
@@ -170,14 +170,14 @@ fn test_show() {
         let b = box Test as Box<Any>;
         let a_str = a.to_str();
         let b_str = b.to_str();
-        assert_eq!(a_str.as_slice(), "Box<Any>");
-        assert_eq!(b_str.as_slice(), "Box<Any>");
+        assert_eq!(a_str, "Box<Any>");
+        assert_eq!(b_str, "Box<Any>");
 
         let a = &8u as &Any;
         let b = &Test as &Any;
         let s = format!("{}", a);
-        assert_eq!(s.as_slice(), "&Any");
+        assert_eq!(s, "&Any");
         let s = format!("{}", b);
-        assert_eq!(s.as_slice(), "&Any");
+        assert_eq!(s, "&Any");
     }
 }
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 330b93929746c037c7a6c591450765c3fd1dab78..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.
@@ -485,7 +487,7 @@ pub fn into_sorted_vec(self) -> Vec<T> {
         let mut end = q.len();
         while end > 1 {
             end -= 1;
-            q.data.as_mut_slice().swap(0, end);
+            q.data.swap(0, end);
             q.siftdown_range(0, end)
         }
         q.into_vec()
@@ -769,8 +771,8 @@ fn check_to_vec(mut data: Vec<int>) {
         v.sort();
         data.sort();
 
-        assert_eq!(v.as_slice(), data.as_slice());
-        assert_eq!(heap.into_sorted_vec().as_slice(), data.as_slice());
+        assert_eq!(v, data);
+        assert_eq!(heap.into_sorted_vec(), data);
     }
 
     #[test]
@@ -812,7 +814,7 @@ fn test_empty_replace() {
     fn test_from_iter() {
         let xs = vec!(9u, 8, 7, 6, 5, 4, 3, 2, 1);
 
-        let mut q: BinaryHeap<uint> = xs.as_slice().iter().rev().map(|&x| x).collect();
+        let mut q: BinaryHeap<uint> = xs.iter().rev().map(|&x| x).collect();
 
         for &x in xs.iter() {
             assert_eq!(q.pop().unwrap(), x);
index 903a9bd982324dcae57494bdb36a438149fdc2f1..ad5732c47a891b88dbb07497fba8ad9d8e46954c 100644 (file)
@@ -1692,10 +1692,10 @@ mod tests {
     #[test]
     fn test_to_str() {
         let zerolen = Bitv::new();
-        assert_eq!(zerolen.to_string().as_slice(), "");
+        assert_eq!(zerolen.to_string(), "");
 
         let eightbits = Bitv::with_capacity(8u, false);
-        assert_eq!(eightbits.to_string().as_slice(), "00000000")
+        assert_eq!(eightbits.to_string(), "00000000")
     }
 
     #[test]
@@ -1718,7 +1718,7 @@ fn test_2_elements() {
         let mut b = bitv::Bitv::with_capacity(2, false);
         b.set(0, true);
         b.set(1, false);
-        assert_eq!(b.to_string().as_slice(), "10");
+        assert_eq!(b.to_string(), "10");
     }
 
     #[test]
@@ -2029,7 +2029,7 @@ fn test_equal_sneaky_big() {
     fn test_from_bytes() {
         let bitv = from_bytes(&[0b10110110, 0b00000000, 0b11111111]);
         let str = format!("{}{}{}", "10110110", "00000000", "11111111");
-        assert_eq!(bitv.to_string().as_slice(), str.as_slice());
+        assert_eq!(bitv.to_string(), str);
     }
 
     #[test]
@@ -2048,7 +2048,7 @@ fn test_to_bytes() {
     fn test_from_bools() {
         let bools = vec![true, false, true, true];
         let bitv: Bitv = bools.iter().map(|n| *n).collect();
-        assert_eq!(bitv.to_string().as_slice(), "1011");
+        assert_eq!(bitv.to_string(), "1011");
     }
 
     #[test]
@@ -2207,7 +2207,7 @@ fn test_bitv_set_intersection() {
 
         let expected = [3, 5, 11, 77];
         let actual = a.intersection(&b).collect::<Vec<uint>>();
-        assert_eq!(actual.as_slice(), expected.as_slice());
+        assert_eq!(actual, expected);
     }
 
     #[test]
@@ -2226,7 +2226,7 @@ fn test_bitv_set_difference() {
 
         let expected = [1, 5, 500];
         let actual = a.difference(&b).collect::<Vec<uint>>();
-        assert_eq!(actual.as_slice(), expected.as_slice());
+        assert_eq!(actual, expected);
     }
 
     #[test]
@@ -2247,7 +2247,7 @@ fn test_bitv_set_symmetric_difference() {
 
         let expected = [1, 5, 11, 14, 220];
         let actual = a.symmetric_difference(&b).collect::<Vec<uint>>();
-        assert_eq!(actual.as_slice(), expected.as_slice());
+        assert_eq!(actual, expected);
     }
 
     #[test]
@@ -2272,7 +2272,7 @@ fn test_bitv_set_union() {
 
         let expected = [1, 3, 5, 9, 11, 13, 19, 24, 160, 200];
         let actual = a.union(&b).collect::<Vec<uint>>();
-        assert_eq!(actual.as_slice(), expected.as_slice());
+        assert_eq!(actual, expected);
     }
 
     #[test]
@@ -2660,7 +2660,7 @@ fn test_bitv_set_show() {
         s.insert(10);
         s.insert(50);
         s.insert(2);
-        assert_eq!("{1, 2, 10, 50}".to_string(), s.to_string());
+        assert_eq!("{1, 2, 10, 50}", s.to_string());
     }
 
     fn rng() -> rand::IsaacRng {
index 8a6d26c26bf3c0651020e7d0fe3dbc447a84ee4b..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();
@@ -1068,12 +1086,38 @@ pub fn into_iter(self) -> MoveEntries<K, V> {
     }
 
     /// Gets an iterator over the keys of the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeMap;
+    ///
+    /// let mut a = BTreeMap::new();
+    /// a.insert(1u, "a");
+    /// a.insert(2u, "b");
+    ///
+    /// let keys: Vec<uint> = a.keys().cloned().collect();
+    /// assert_eq!(keys, vec![1u,2,]);
+    /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
         self.iter().map(|(k, _)| k)
     }
 
     /// Gets an iterator over the values of the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeMap;
+    ///
+    /// let mut a = BTreeMap::new();
+    /// a.insert(1u, "a");
+    /// a.insert(2u, "b");
+    ///
+    /// let values: Vec<&str> = a.values().cloned().collect();
+    /// assert_eq!(values, vec!["a","b"]);
+    /// ```
     #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn values<'a>(&'a self) -> Values<'a, K, V> {
         self.iter().map(|(_, v)| v)
index b40ff35cca1c62707a69374a76ea79f95d0bdc2c..3f53bad6518f22e40b581b909833374860a65174 100644 (file)
@@ -158,43 +158,43 @@ pub fn is_full(&self) -> bool {
     /// Swap the given key-value pair with the key-value pair stored in the node's index,
     /// without checking bounds.
     pub unsafe fn unsafe_swap(&mut self, index: uint, key: &mut K, val: &mut V) {
-        mem::swap(self.keys.as_mut_slice().unsafe_mut(index), key);
-        mem::swap(self.vals.as_mut_slice().unsafe_mut(index), val);
+        mem::swap(self.keys.unsafe_mut(index), key);
+        mem::swap(self.vals.unsafe_mut(index), val);
     }
 
     /// Get the node's key mutably without any bounds checks.
     pub unsafe fn unsafe_key_mut(&mut self, index: uint) -> &mut K {
-        self.keys.as_mut_slice().unsafe_mut(index)
+        self.keys.unsafe_mut(index)
     }
 
     /// Get the node's value at the given index
     pub fn val(&self, index: uint) -> Option<&V> {
-        self.vals.as_slice().get(index)
+        self.vals.get(index)
     }
 
     /// Get the node's value at the given index
     pub fn val_mut(&mut self, index: uint) -> Option<&mut V> {
-        self.vals.as_mut_slice().get_mut(index)
+        self.vals.get_mut(index)
     }
 
     /// Get the node's value mutably without any bounds checks.
     pub unsafe fn unsafe_val_mut(&mut self, index: uint) -> &mut V {
-        self.vals.as_mut_slice().unsafe_mut(index)
+        self.vals.unsafe_mut(index)
     }
 
     /// Get the node's edge at the given index
     pub fn edge(&self, index: uint) -> Option<&Node<K,V>> {
-        self.edges.as_slice().get(index)
+        self.edges.get(index)
     }
 
     /// Get the node's edge mutably at the given index
     pub fn edge_mut(&mut self, index: uint) -> Option<&mut Node<K,V>> {
-        self.edges.as_mut_slice().get_mut(index)
+        self.edges.get_mut(index)
     }
 
     /// Get the node's edge mutably without any bounds checks.
     pub unsafe fn unsafe_edge_mut(&mut self, index: uint) -> &mut Node<K,V> {
-        self.edges.as_mut_slice().unsafe_mut(index)
+        self.edges.unsafe_mut(index)
     }
 
     /// Pop an edge off the end of the node
@@ -281,8 +281,8 @@ pub fn handle_underflow(&mut self, underflowed_child_index: uint) {
     pub fn iter<'a>(&'a self) -> Traversal<'a, K, V> {
         let is_leaf = self.is_leaf();
         Traversal {
-            elems: self.keys.as_slice().iter().zip(self.vals.as_slice().iter()),
-            edges: self.edges.as_slice().iter(),
+            elems: self.keys.iter().zip(self.vals.iter()),
+            edges: self.edges.iter(),
             head_is_edge: true,
             tail_is_edge: true,
             has_edges: !is_leaf,
@@ -292,8 +292,8 @@ pub fn iter<'a>(&'a self) -> Traversal<'a, K, V> {
     pub fn iter_mut<'a>(&'a mut self) -> MutTraversal<'a, K, V> {
         let is_leaf = self.is_leaf();
         MutTraversal {
-            elems: self.keys.as_slice().iter().zip(self.vals.as_mut_slice().iter_mut()),
-            edges: self.edges.as_mut_slice().iter_mut(),
+            elems: self.keys.iter().zip(self.vals.iter_mut()),
+            edges: self.edges.iter_mut(),
             head_is_edge: true,
             tail_is_edge: true,
             has_edges: !is_leaf,
@@ -477,8 +477,8 @@ fn split<T>(left: &mut Vec<T>) -> Vec<T> {
     let left_len = len - right_len;
     let mut right = Vec::with_capacity(left.capacity());
     unsafe {
-        let left_ptr = left.as_slice().unsafe_get(left_len) as *const _;
-        let right_ptr = right.as_mut_slice().as_mut_ptr();
+        let left_ptr = left.unsafe_get(left_len) as *const _;
+        let right_ptr = right.as_mut_ptr();
         ptr::copy_nonoverlapping_memory(right_ptr, left_ptr, right_len);
         left.set_len(left_len);
         right.set_len(right_len);
index 3973b4774b3ae9bbfcb3fa08bfe40df4387ea2fe..573b5a9422b84be9cb3badfa351432de67668417 100644 (file)
@@ -646,7 +646,7 @@ fn test_show() {
 
         let set_str = format!("{}", set);
 
-        assert!(set_str == "{1, 2}".to_string());
-        assert_eq!(format!("{}", empty), "{}".to_string());
+        assert!(set_str == "{1, 2}");
+        assert_eq!(format!("{}", empty), "{}");
     }
 }
index 39cdf0c456413d48f81393993d3168591c525e64..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>,
@@ -926,7 +930,7 @@ fn test_prepend() {
         let mut m = list_from(v.as_slice());
         m.prepend(list_from(u.as_slice()));
         check_links(&m);
-        u.extend(v.as_slice().iter().map(|&b| b));
+        u.extend(v.iter().map(|&b| b));
         assert_eq!(u.len(), m.len());
         for elt in u.into_iter() {
             assert_eq!(m.pop_front(), Some(elt))
@@ -1133,7 +1137,7 @@ fn test_send() {
         spawn(proc() {
             check_links(&n);
             let a: &[_] = &[&1,&2,&3];
-            assert_eq!(a, n.iter().collect::<Vec<&int>>().as_slice());
+            assert_eq!(a, n.iter().collect::<Vec<&int>>());
         });
     }
 
@@ -1224,12 +1228,12 @@ fn test_fuzz() {
     #[test]
     fn test_show() {
         let list: DList<int> = range(0i, 10).collect();
-        assert!(list.to_string().as_slice() == "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
+        assert!(list.to_string() == "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
 
         let list: DList<&str> = vec!["just", "one", "test", "more"].iter()
                                                                    .map(|&s| s)
                                                                    .collect();
-        assert!(list.to_string().as_slice() == "[just, one, test, more]");
+        assert!(list.to_string() == "[just, one, test, more]");
     }
 
     #[cfg(test)]
index 2cbde0168a2e80444c13641f2557a26e0cc7842d..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
@@ -288,11 +292,11 @@ fn test_new() {
     #[test]
     fn test_show() {
         let mut e = EnumSet::new();
-        assert_eq!("{}", e.to_string().as_slice());
+        assert_eq!("{}", e.to_string());
         e.insert(A);
-        assert_eq!("{A}", e.to_string().as_slice());
+        assert_eq!("{A}", e.to_string());
         e.insert(C);
-        assert_eq!("{A, C}", e.to_string().as_slice());
+        assert_eq!("{A, C}", e.to_string());
     }
 
     #[test]
@@ -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 e11ba35367e2eb56770887eb8e3ea9cdb9f18af6..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
@@ -1246,7 +1245,7 @@ fn test_iter() {
         }
         {
             let b: &[_] = &[&0,&1,&2,&3,&4];
-            assert_eq!(d.iter().collect::<Vec<&int>>().as_slice(), b);
+            assert_eq!(d.iter().collect::<Vec<&int>>(), b);
         }
 
         for i in range(6i, 9) {
@@ -1254,7 +1253,7 @@ fn test_iter() {
         }
         {
             let b: &[_] = &[&8,&7,&6,&0,&1,&2,&3,&4];
-            assert_eq!(d.iter().collect::<Vec<&int>>().as_slice(), b);
+            assert_eq!(d.iter().collect::<Vec<&int>>(), b);
         }
 
         let mut it = d.iter();
@@ -1277,14 +1276,14 @@ fn test_rev_iter() {
         }
         {
             let b: &[_] = &[&4,&3,&2,&1,&0];
-            assert_eq!(d.iter().rev().collect::<Vec<&int>>().as_slice(), b);
+            assert_eq!(d.iter().rev().collect::<Vec<&int>>(), b);
         }
 
         for i in range(6i, 9) {
             d.push_front(i);
         }
         let b: &[_] = &[&4,&3,&2,&1,&0,&6,&7,&8];
-        assert_eq!(d.iter().rev().collect::<Vec<&int>>().as_slice(), b);
+        assert_eq!(d.iter().rev().collect::<Vec<&int>>(), b);
     }
 
     #[test]
@@ -1495,12 +1494,12 @@ fn test_ord() {
     #[test]
     fn test_show() {
         let ringbuf: RingBuf<int> = range(0i, 10).collect();
-        assert!(format!("{}", ringbuf).as_slice() == "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
+        assert!(format!("{}", ringbuf) == "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
 
         let ringbuf: RingBuf<&str> = vec!["just", "one", "test", "more"].iter()
                                                                         .map(|&s| s)
                                                                         .collect();
-        assert!(format!("{}", ringbuf).as_slice() == "[just, one, test, more]");
+        assert!(format!("{}", ringbuf) == "[just, one, test, more]");
     }
 
     #[test]
index 6c13abdaf892f52fd2460fdcf57c94dd93b096d5..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)> {
@@ -201,7 +205,7 @@ fn new_pos(i: uint, s: Direction) -> uint {
         match max {
             Some((i, sd)) => {
                 let j = new_pos(i, sd.dir);
-                self.sdir.as_mut_slice().swap(i, j);
+                self.sdir.swap(i, j);
 
                 // Swap the direction of each larger SizeDirection
                 for x in self.sdir.iter_mut() {
@@ -256,7 +260,7 @@ fn next(&mut self) -> Option<Vec<T>> {
             Some((0,0)) => Some(self.v.clone()),
             Some((a, b)) => {
                 let elt = self.v.clone();
-                self.v.as_mut_slice().swap(a, b);
+                self.v.swap(a, b);
                 Some(elt)
             }
         }
@@ -779,11 +783,11 @@ fn test_head() {
     #[test]
     fn test_head_mut() {
         let mut a = vec![];
-        assert_eq!(a.as_mut_slice().head_mut(), None);
+        assert_eq!(a.head_mut(), None);
         a = vec![11i];
-        assert_eq!(*a.as_mut_slice().head_mut().unwrap(), 11);
+        assert_eq!(*a.head_mut().unwrap(), 11);
         a = vec![11i, 12];
-        assert_eq!(*a.as_mut_slice().head_mut().unwrap(), 11);
+        assert_eq!(*a.head_mut().unwrap(), 11);
     }
 
     #[test]
@@ -800,10 +804,10 @@ fn test_tail() {
     fn test_tail_mut() {
         let mut a = vec![11i];
         let b: &mut [int] = &mut [];
-        assert!(a.as_mut_slice().tail_mut() == b);
+        assert!(a.tail_mut() == b);
         a = vec![11i, 12];
         let b: &mut [int] = &mut [12];
-        assert!(a.as_mut_slice().tail_mut() == b);
+        assert!(a.tail_mut() == b);
     }
 
     #[test]
@@ -817,7 +821,7 @@ fn test_tail_empty() {
     #[should_fail]
     fn test_tail_mut_empty() {
         let mut a: Vec<int> = vec![];
-        a.as_mut_slice().tail_mut();
+        a.tail_mut();
     }
 
     #[test]
@@ -834,10 +838,10 @@ fn test_init() {
     fn test_init_mut() {
         let mut a = vec![11i];
         let b: &mut [int] = &mut [];
-        assert!(a.as_mut_slice().init_mut() == b);
+        assert!(a.init_mut() == b);
         a = vec![11i, 12];
         let b: &mut [int] = &mut [11];
-        assert!(a.as_mut_slice().init_mut() == b);
+        assert!(a.init_mut() == b);
     }
 
     #[test]
@@ -851,7 +855,7 @@ fn test_init_empty() {
     #[should_fail]
     fn test_init_mut_empty() {
         let mut a: Vec<int> = vec![];
-        a.as_mut_slice().init_mut();
+        a.init_mut();
     }
 
     #[test]
@@ -867,11 +871,11 @@ fn test_last() {
     #[test]
     fn test_last_mut() {
         let mut a = vec![];
-        assert_eq!(a.as_mut_slice().last_mut(), None);
+        assert_eq!(a.last_mut(), None);
         a = vec![11i];
-        assert_eq!(*a.as_mut_slice().last_mut().unwrap(), 11);
+        assert_eq!(*a.last_mut().unwrap(), 11);
         a = vec![11i, 12];
-        assert_eq!(*a.as_mut_slice().last_mut().unwrap(), 12);
+        assert_eq!(*a.last_mut().unwrap(), 12);
     }
 
     #[test]
@@ -1299,13 +1303,13 @@ fn test_sort() {
                                       .collect::<Vec<uint>>();
                 let mut v1 = v.clone();
 
-                v.as_mut_slice().sort();
+                v.sort();
                 assert!(v.as_slice().windows(2).all(|w| w[0] <= w[1]));
 
-                v1.as_mut_slice().sort_by(|a, b| a.cmp(b));
+                v1.sort_by(|a, b| a.cmp(b));
                 assert!(v1.as_slice().windows(2).all(|w| w[0] <= w[1]));
 
-                v1.as_mut_slice().sort_by(|a, b| b.cmp(a));
+                v1.sort_by(|a, b| b.cmp(a));
                 assert!(v1.as_slice().windows(2).all(|w| w[0] >= w[1]));
             }
         }
@@ -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);
     }
 
@@ -1652,24 +1662,24 @@ fn test_splitator() {
         let xs = &[1i,2,3,4,5];
 
         let splits: &[&[int]] = &[&[1], &[3], &[5]];
-        assert_eq!(xs.split(|x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
+        assert_eq!(xs.split(|x| *x % 2 == 0).collect::<Vec<&[int]>>(),
                    splits);
         let splits: &[&[int]] = &[&[], &[2,3,4,5]];
-        assert_eq!(xs.split(|x| *x == 1).collect::<Vec<&[int]>>().as_slice(),
+        assert_eq!(xs.split(|x| *x == 1).collect::<Vec<&[int]>>(),
                    splits);
         let splits: &[&[int]] = &[&[1,2,3,4], &[]];
-        assert_eq!(xs.split(|x| *x == 5).collect::<Vec<&[int]>>().as_slice(),
+        assert_eq!(xs.split(|x| *x == 5).collect::<Vec<&[int]>>(),
                    splits);
         let splits: &[&[int]] = &[&[1,2,3,4,5]];
-        assert_eq!(xs.split(|x| *x == 10).collect::<Vec<&[int]>>().as_slice(),
+        assert_eq!(xs.split(|x| *x == 10).collect::<Vec<&[int]>>(),
                    splits);
         let splits: &[&[int]] = &[&[], &[], &[], &[], &[], &[]];
-        assert_eq!(xs.split(|_| true).collect::<Vec<&[int]>>().as_slice(),
+        assert_eq!(xs.split(|_| true).collect::<Vec<&[int]>>(),
                    splits);
 
         let xs: &[int] = &[];
         let splits: &[&[int]] = &[&[]];
-        assert_eq!(xs.split(|x| *x == 5).collect::<Vec<&[int]>>().as_slice(), splits);
+        assert_eq!(xs.split(|x| *x == 5).collect::<Vec<&[int]>>(), splits);
     }
 
     #[test]
@@ -1677,18 +1687,18 @@ fn test_splitnator() {
         let xs = &[1i,2,3,4,5];
 
         let splits: &[&[int]] = &[&[1,2,3,4,5]];
-        assert_eq!(xs.splitn(0, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
+        assert_eq!(xs.splitn(0, |x| *x % 2 == 0).collect::<Vec<&[int]>>(),
                    splits);
         let splits: &[&[int]] = &[&[1], &[3,4,5]];
-        assert_eq!(xs.splitn(1, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
+        assert_eq!(xs.splitn(1, |x| *x % 2 == 0).collect::<Vec<&[int]>>(),
                    splits);
         let splits: &[&[int]] = &[&[], &[], &[], &[4,5]];
-        assert_eq!(xs.splitn(3, |_| true).collect::<Vec<&[int]>>().as_slice(),
+        assert_eq!(xs.splitn(3, |_| true).collect::<Vec<&[int]>>(),
                    splits);
 
         let xs: &[int] = &[];
         let splits: &[&[int]] = &[&[]];
-        assert_eq!(xs.splitn(1, |x| *x == 5).collect::<Vec<&[int]>>().as_slice(), splits);
+        assert_eq!(xs.splitn(1, |x| *x == 5).collect::<Vec<&[int]>>(), splits);
     }
 
     #[test]
@@ -1696,18 +1706,18 @@ fn test_splitnator_mut() {
         let xs = &mut [1i,2,3,4,5];
 
         let splits: &[&mut [int]] = &[&mut [1,2,3,4,5]];
-        assert_eq!(xs.splitn_mut(0, |x| *x % 2 == 0).collect::<Vec<&mut [int]>>().as_slice(),
+        assert_eq!(xs.splitn_mut(0, |x| *x % 2 == 0).collect::<Vec<&mut [int]>>(),
                    splits);
         let splits: &[&mut [int]] = &[&mut [1], &mut [3,4,5]];
-        assert_eq!(xs.splitn_mut(1, |x| *x % 2 == 0).collect::<Vec<&mut [int]>>().as_slice(),
+        assert_eq!(xs.splitn_mut(1, |x| *x % 2 == 0).collect::<Vec<&mut [int]>>(),
                    splits);
         let splits: &[&mut [int]] = &[&mut [], &mut [], &mut [], &mut [4,5]];
-        assert_eq!(xs.splitn_mut(3, |_| true).collect::<Vec<&mut [int]>>().as_slice(),
+        assert_eq!(xs.splitn_mut(3, |_| true).collect::<Vec<&mut [int]>>(),
                    splits);
 
         let xs: &mut [int] = &mut [];
         let splits: &[&mut [int]] = &[&mut []];
-        assert_eq!(xs.splitn_mut(1, |x| *x == 5).collect::<Vec<&mut [int]>>().as_slice(),
+        assert_eq!(xs.splitn_mut(1, |x| *x == 5).collect::<Vec<&mut [int]>>(),
                    splits);
     }
 
@@ -1716,21 +1726,21 @@ fn test_rsplitator() {
         let xs = &[1i,2,3,4,5];
 
         let splits: &[&[int]] = &[&[5], &[3], &[1]];
-        assert_eq!(xs.split(|x| *x % 2 == 0).rev().collect::<Vec<&[int]>>().as_slice(),
+        assert_eq!(xs.split(|x| *x % 2 == 0).rev().collect::<Vec<&[int]>>(),
                    splits);
         let splits: &[&[int]] = &[&[2,3,4,5], &[]];
-        assert_eq!(xs.split(|x| *x == 1).rev().collect::<Vec<&[int]>>().as_slice(),
+        assert_eq!(xs.split(|x| *x == 1).rev().collect::<Vec<&[int]>>(),
                    splits);
         let splits: &[&[int]] = &[&[], &[1,2,3,4]];
-        assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<&[int]>>().as_slice(),
+        assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<&[int]>>(),
                    splits);
         let splits: &[&[int]] = &[&[1,2,3,4,5]];
-        assert_eq!(xs.split(|x| *x == 10).rev().collect::<Vec<&[int]>>().as_slice(),
+        assert_eq!(xs.split(|x| *x == 10).rev().collect::<Vec<&[int]>>(),
                    splits);
 
         let xs: &[int] = &[];
         let splits: &[&[int]] = &[&[]];
-        assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<&[int]>>().as_slice(), splits);
+        assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<&[int]>>(), splits);
     }
 
     #[test]
@@ -1738,18 +1748,18 @@ fn test_rsplitnator() {
         let xs = &[1,2,3,4,5];
 
         let splits: &[&[int]] = &[&[1,2,3,4,5]];
-        assert_eq!(xs.rsplitn(0, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
+        assert_eq!(xs.rsplitn(0, |x| *x % 2 == 0).collect::<Vec<&[int]>>(),
                    splits);
         let splits: &[&[int]] = &[&[5], &[1,2,3]];
-        assert_eq!(xs.rsplitn(1, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
+        assert_eq!(xs.rsplitn(1, |x| *x % 2 == 0).collect::<Vec<&[int]>>(),
                    splits);
         let splits: &[&[int]] = &[&[], &[], &[], &[1,2]];
-        assert_eq!(xs.rsplitn(3, |_| true).collect::<Vec<&[int]>>().as_slice(),
+        assert_eq!(xs.rsplitn(3, |_| true).collect::<Vec<&[int]>>(),
                    splits);
 
         let xs: &[int] = &[];
         let splits: &[&[int]] = &[&[]];
-        assert_eq!(xs.rsplitn(1, |x| *x == 5).collect::<Vec<&[int]>>().as_slice(), splits);
+        assert_eq!(xs.rsplitn(1, |x| *x == 5).collect::<Vec<&[int]>>(), splits);
     }
 
     #[test]
@@ -1757,9 +1767,9 @@ fn test_windowsator() {
         let v = &[1i,2,3,4];
 
         let wins: &[&[int]] = &[&[1,2], &[2,3], &[3,4]];
-        assert_eq!(v.windows(2).collect::<Vec<&[int]>>().as_slice(), wins);
+        assert_eq!(v.windows(2).collect::<Vec<&[int]>>(), wins);
         let wins: &[&[int]] = &[&[1i,2,3], &[2,3,4]];
-        assert_eq!(v.windows(3).collect::<Vec<&[int]>>().as_slice(), wins);
+        assert_eq!(v.windows(3).collect::<Vec<&[int]>>(), wins);
         assert!(v.windows(6).next().is_none());
     }
 
@@ -1775,14 +1785,14 @@ fn test_chunksator() {
         let v = &[1i,2,3,4,5];
 
         let chunks: &[&[int]] = &[&[1i,2], &[3,4], &[5]];
-        assert_eq!(v.chunks(2).collect::<Vec<&[int]>>().as_slice(), chunks);
+        assert_eq!(v.chunks(2).collect::<Vec<&[int]>>(), chunks);
         let chunks: &[&[int]] = &[&[1i,2,3], &[4,5]];
-        assert_eq!(v.chunks(3).collect::<Vec<&[int]>>().as_slice(), chunks);
+        assert_eq!(v.chunks(3).collect::<Vec<&[int]>>(), chunks);
         let chunks: &[&[int]] = &[&[1i,2,3,4,5]];
-        assert_eq!(v.chunks(6).collect::<Vec<&[int]>>().as_slice(), chunks);
+        assert_eq!(v.chunks(6).collect::<Vec<&[int]>>(), chunks);
 
         let chunks: &[&[int]] = &[&[5i], &[3,4], &[1,2]];
-        assert_eq!(v.chunks(2).rev().collect::<Vec<&[int]>>().as_slice(), chunks);
+        assert_eq!(v.chunks(2).rev().collect::<Vec<&[int]>>(), chunks);
         let mut it = v.chunks(2);
         assert_eq!(it.indexable(), 3);
         let chunk: &[int] = &[1,2];
@@ -1838,20 +1848,20 @@ macro_rules! test_show_vec(
             })
         )
         let empty: Vec<int> = vec![];
-        test_show_vec!(empty, "[]".to_string());
-        test_show_vec!(vec![1i], "[1]".to_string());
-        test_show_vec!(vec![1i, 2, 3], "[1, 2, 3]".to_string());
+        test_show_vec!(empty, "[]");
+        test_show_vec!(vec![1i], "[1]");
+        test_show_vec!(vec![1i, 2, 3], "[1, 2, 3]");
         test_show_vec!(vec![vec![], vec![1u], vec![1u, 1u]],
-                       "[[], [1], [1, 1]]".to_string());
+                       "[[], [1], [1, 1]]");
 
         let empty_mut: &mut [int] = &mut[];
-        test_show_vec!(empty_mut, "[]".to_string());
+        test_show_vec!(empty_mut, "[]");
         let v: &mut[int] = &mut[1];
-        test_show_vec!(v, "[1]".to_string());
+        test_show_vec!(v, "[1]");
         let v: &mut[int] = &mut[1, 2, 3];
-        test_show_vec!(v, "[1, 2, 3]".to_string());
+        test_show_vec!(v, "[1, 2, 3]");
         let v: &mut [&mut[uint]] = &mut[&mut[], &mut[1u], &mut[1u, 1u]];
-        test_show_vec!(v, "[[], [1], [1, 1]]".to_string());
+        test_show_vec!(v, "[[], [1], [1, 1]]");
     }
 
     #[test]
@@ -2081,7 +2091,7 @@ fn test_mut_last() {
     fn test_to_vec() {
         let xs = box [1u, 2, 3];
         let ys = xs.to_vec();
-        assert_eq!(ys.as_slice(), [1u, 2, 3].as_slice());
+        assert_eq!(ys, [1u, 2, 3]);
     }
 }
 
index 78cdda61104f1a8107cf775b255af07f7a4563b6..419d7f270adf197e8eea9f2035a7c4f4f7a54991 100644 (file)
@@ -215,7 +215,7 @@ pub struct Decompositions<'a> {
 impl<'a> Iterator<char> for Decompositions<'a> {
     #[inline]
     fn next(&mut self) -> Option<char> {
-        match self.buffer.as_slice().head() {
+        match self.buffer.head() {
             Some(&(c, 0)) => {
                 self.sorted = false;
                 self.buffer.remove(0);
@@ -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
+                }
             }
         }
 
@@ -915,10 +923,10 @@ fn test_rfind() {
     #[test]
     fn test_collect() {
         let empty = String::from_str("");
-        let s: String = empty.as_slice().chars().collect();
+        let s: String = empty.chars().collect();
         assert_eq!(empty, s);
         let data = String::from_str("ประเทศไทย中");
-        let s: String = data.as_slice().chars().collect();
+        let s: String = data.chars().collect();
         assert_eq!(data, s);
     }
 
@@ -926,7 +934,7 @@ fn test_collect() {
     fn test_into_bytes() {
         let data = String::from_str("asdf");
         let buf = data.into_bytes();
-        assert_eq!(b"asdf", buf.as_slice());
+        assert_eq!(b"asdf", buf);
     }
 
     #[test]
@@ -943,21 +951,21 @@ fn test_find_str() {
         let string = "ประเทศไทย中华Việt Nam";
         let mut data = String::from_str(string);
         data.push_str(string);
-        assert!(data.as_slice().find_str("ไท华").is_none());
-        assert_eq!(data.as_slice().slice(0u, 43u).find_str(""), Some(0u));
-        assert_eq!(data.as_slice().slice(6u, 43u).find_str(""), Some(6u - 6u));
+        assert!(data.find_str("ไท华").is_none());
+        assert_eq!(data.slice(0u, 43u).find_str(""), Some(0u));
+        assert_eq!(data.slice(6u, 43u).find_str(""), Some(6u - 6u));
 
-        assert_eq!(data.as_slice().slice(0u, 43u).find_str("ประ"), Some( 0u));
-        assert_eq!(data.as_slice().slice(0u, 43u).find_str("ทศไ"), Some(12u));
-        assert_eq!(data.as_slice().slice(0u, 43u).find_str("ย中"), Some(24u));
-        assert_eq!(data.as_slice().slice(0u, 43u).find_str("iệt"), Some(34u));
-        assert_eq!(data.as_slice().slice(0u, 43u).find_str("Nam"), Some(40u));
+        assert_eq!(data.slice(0u, 43u).find_str("ประ"), Some( 0u));
+        assert_eq!(data.slice(0u, 43u).find_str("ทศไ"), Some(12u));
+        assert_eq!(data.slice(0u, 43u).find_str("ย中"), Some(24u));
+        assert_eq!(data.slice(0u, 43u).find_str("iệt"), Some(34u));
+        assert_eq!(data.slice(0u, 43u).find_str("Nam"), Some(40u));
 
-        assert_eq!(data.as_slice().slice(43u, 86u).find_str("ประ"), Some(43u - 43u));
-        assert_eq!(data.as_slice().slice(43u, 86u).find_str("ทศไ"), Some(55u - 43u));
-        assert_eq!(data.as_slice().slice(43u, 86u).find_str("ย中"), Some(67u - 43u));
-        assert_eq!(data.as_slice().slice(43u, 86u).find_str("iệt"), Some(77u - 43u));
-        assert_eq!(data.as_slice().slice(43u, 86u).find_str("Nam"), Some(83u - 43u));
+        assert_eq!(data.slice(43u, 86u).find_str("ประ"), Some(43u - 43u));
+        assert_eq!(data.slice(43u, 86u).find_str("ทศไ"), Some(55u - 43u));
+        assert_eq!(data.slice(43u, 86u).find_str("ย中"), Some(67u - 43u));
+        assert_eq!(data.slice(43u, 86u).find_str("iệt"), Some(77u - 43u));
+        assert_eq!(data.slice(43u, 86u).find_str("Nam"), Some(83u - 43u));
     }
 
     #[test]
@@ -989,7 +997,7 @@ macro_rules! test_concat {
         ($expected: expr, $string: expr) => {
             {
                 let s = $string.concat();
-                assert_eq!($expected, s.as_slice());
+                assert_eq!($expected, s);
             }
         }
     }
@@ -1027,7 +1035,7 @@ macro_rules! test_connect {
         ($expected: expr, $string: expr, $delim: expr) => {
             {
                 let s = $string.connect($delim);
-                assert_eq!($expected, s.as_slice());
+                assert_eq!($expected, s);
             }
         }
     }
@@ -1148,7 +1156,7 @@ fn test_replace_2a() {
 
         let a = "ประเ";
         let a2 = "دولة الكويتทศไทย中华";
-        assert_eq!(data.replace(a, repl).as_slice(), a2);
+        assert_eq!(data.replace(a, repl), a2);
     }
 
     #[test]
@@ -1158,7 +1166,7 @@ fn test_replace_2b() {
 
         let b = "ะเ";
         let b2 = "ปรدولة الكويتทศไทย中华";
-        assert_eq!(data.replace(b, repl).as_slice(), b2);
+        assert_eq!(data.replace(b, repl), b2);
     }
 
     #[test]
@@ -1168,7 +1176,7 @@ fn test_replace_2c() {
 
         let c = "中华";
         let c2 = "ประเทศไทยدولة الكويت";
-        assert_eq!(data.replace(c, repl).as_slice(), c2);
+        assert_eq!(data.replace(c, repl), c2);
     }
 
     #[test]
@@ -1177,7 +1185,7 @@ fn test_replace_2d() {
         let repl = "دولة الكويت";
 
         let d = "ไท华";
-        assert_eq!(data.replace(d, repl).as_slice(), data);
+        assert_eq!(data.replace(d, repl), data);
     }
 
     #[test]
@@ -1213,7 +1221,7 @@ fn half_a_million_letter_x() -> String {
         }
         let letters = a_million_letter_x();
         assert!(half_a_million_letter_x() ==
-            String::from_str(letters.as_slice().slice(0u, 3u * 500000u)));
+            String::from_str(letters.slice(0u, 3u * 500000u)));
     }
 
     #[test]
@@ -1452,7 +1460,7 @@ fn test_as_bytes() {
         let b: &[u8] = &[];
         assert_eq!("".as_bytes(), b);
         assert_eq!("abc".as_bytes(), b"abc");
-        assert_eq!("ศไทย中华Việt Nam".as_bytes(), v.as_slice());
+        assert_eq!("ศไทย中华Việt Nam".as_bytes(), v);
     }
 
     #[test]
@@ -1487,7 +1495,6 @@ fn test_subslice_offset() {
 
         let string = "a\nb\nc";
         let lines: Vec<&str> = string.lines().collect();
-        let lines = lines.as_slice();
         assert_eq!(string.subslice_offset(lines[0]), 0);
         assert_eq!(string.subslice_offset(lines[1]), 2);
         assert_eq!(string.subslice_offset(lines[2]), 4);
@@ -1834,7 +1841,7 @@ fn test_lev_distance() {
     fn test_nfd_chars() {
         macro_rules! t {
             ($input: expr, $expected: expr) => {
-                assert_eq!($input.nfd_chars().collect::<String>(), $expected.into_string());
+                assert_eq!($input.nfd_chars().collect::<String>(), $expected);
             }
         }
         t!("abc", "abc");
@@ -1853,7 +1860,7 @@ macro_rules! t {
     fn test_nfkd_chars() {
         macro_rules! t {
             ($input: expr, $expected: expr) => {
-                assert_eq!($input.nfkd_chars().collect::<String>(), $expected.into_string());
+                assert_eq!($input.nfkd_chars().collect::<String>(), $expected);
             }
         }
         t!("abc", "abc");
@@ -1872,7 +1879,7 @@ macro_rules! t {
     fn test_nfc_chars() {
         macro_rules! t {
             ($input: expr, $expected: expr) => {
-                assert_eq!($input.nfc_chars().collect::<String>(), $expected.into_string());
+                assert_eq!($input.nfc_chars().collect::<String>(), $expected);
             }
         }
         t!("abc", "abc");
@@ -1892,7 +1899,7 @@ macro_rules! t {
     fn test_nfkc_chars() {
         macro_rules! t {
             ($input: expr, $expected: expr) => {
-                assert_eq!($input.nfkc_chars().collect::<String>(), $expected.into_string());
+                assert_eq!($input.nfkc_chars().collect::<String>(), $expected);
             }
         }
         t!("abc", "abc");
@@ -2183,10 +2190,10 @@ fn test_graphemes() {
         let s = "a̐éö̲\r\n";
         let gr_inds = s.grapheme_indices(true).collect::<Vec<(uint, &str)>>();
         let b: &[_] = &[(0u, "a̐"), (3, "é"), (6, "ö̲"), (11, "\r\n")];
-        assert_eq!(gr_inds.as_slice(), b);
+        assert_eq!(gr_inds, b);
         let gr_inds = s.grapheme_indices(true).rev().collect::<Vec<(uint, &str)>>();
         let b: &[_] = &[(11, "\r\n"), (6, "ö̲"), (3, "é"), (0u, "a̐")];
-        assert_eq!(gr_inds.as_slice(), b);
+        assert_eq!(gr_inds, b);
         let mut gr_inds_iter = s.grapheme_indices(true);
         {
             let gr_inds = gr_inds_iter.by_ref();
@@ -2202,14 +2209,14 @@ fn test_graphemes() {
         let s = "\n\r\n\r";
         let gr = s.graphemes(true).rev().collect::<Vec<&str>>();
         let b: &[_] = &["\r", "\r\n", "\n"];
-        assert_eq!(gr.as_slice(), b);
+        assert_eq!(gr, b);
     }
 
     #[test]
     fn test_split_strator() {
         fn t(s: &str, sep: &str, u: &[&str]) {
             let v: Vec<&str> = s.split_str(sep).collect();
-            assert_eq!(v.as_slice(), u.as_slice());
+            assert_eq!(v, u);
         }
         t("--1233345--", "12345", &["--1233345--"]);
         t("abc::hello::there", "::", &["abc", "hello", "there"]);
index aa344ccbffed2d9b8cffdeb6422a9949644b6bae..0f86b5ffa684a2d8a185ee637ff6bfc675d9ec2b 100644 (file)
@@ -559,7 +559,7 @@ pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
     #[inline]
     #[unstable = "the panic conventions for strings are under development"]
     pub fn truncate(&mut self, new_len: uint) {
-        assert!(self.as_slice().is_char_boundary(new_len));
+        assert!(self.is_char_boundary(new_len));
         self.vec.truncate(new_len)
     }
 
@@ -583,7 +583,7 @@ pub fn pop(&mut self) -> Option<char> {
             return None
         }
 
-        let CharRange {ch, next} = self.as_slice().char_range_at_reverse(len);
+        let CharRange {ch, next} = self.char_range_at_reverse(len);
         unsafe {
             self.vec.set_len(next);
         }
@@ -618,7 +618,7 @@ pub fn remove(&mut self, idx: uint) -> Option<char> {
         let len = self.len();
         if idx >= len { return None }
 
-        let CharRange { ch, next } = self.as_slice().char_range_at(idx);
+        let CharRange { ch, next } = self.char_range_at(idx);
         unsafe {
             ptr::copy_memory(self.vec.as_mut_ptr().offset(idx as int),
                              self.vec.as_ptr().offset(next as int),
@@ -643,7 +643,7 @@ pub fn remove(&mut self, idx: uint) -> Option<char> {
     pub fn insert(&mut self, idx: uint, ch: char) {
         let len = self.len();
         assert!(idx <= len);
-        assert!(self.as_slice().is_char_boundary(idx));
+        assert!(self.is_char_boundary(idx));
         self.vec.reserve(4);
         let mut bits = [0, ..4];
         let amt = ch.encode_utf8(&mut bits).unwrap();
@@ -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) }
@@ -1105,7 +1128,7 @@ fn test_from_utf16() {
 
         for p in pairs.iter() {
             let (s, u) = (*p).clone();
-            let s_as_utf16 = s.as_slice().utf16_units().collect::<Vec<u16>>();
+            let s_as_utf16 = s.utf16_units().collect::<Vec<u16>>();
             let u_as_string = String::from_utf16(u.as_slice()).unwrap();
 
             assert!(str::is_utf16(u.as_slice()));
@@ -1115,7 +1138,7 @@ fn test_from_utf16() {
             assert_eq!(String::from_utf16_lossy(u.as_slice()), s);
 
             assert_eq!(String::from_utf16(s_as_utf16.as_slice()).unwrap(), s);
-            assert_eq!(u_as_string.as_slice().utf16_units().collect::<Vec<u16>>(), u);
+            assert_eq!(u_as_string.utf16_units().collect::<Vec<u16>>(), u);
         }
     }
 
@@ -1175,18 +1198,18 @@ fn test_push_bytes() {
             let mv = s.as_mut_vec();
             mv.push_all(&[b'D']);
         }
-        assert_eq!(s.as_slice(), "ABCD");
+        assert_eq!(s, "ABCD");
     }
 
     #[test]
     fn test_push_str() {
         let mut s = String::new();
         s.push_str("");
-        assert_eq!(s.as_slice().slice_from(0), "");
+        assert_eq!(s.slice_from(0), "");
         s.push_str("abc");
-        assert_eq!(s.as_slice().slice_from(0), "abc");
+        assert_eq!(s.slice_from(0), "abc");
         s.push_str("ประเทศไทย中华Việt Nam");
-        assert_eq!(s.as_slice().slice_from(0), "abcประเทศไทย中华Việt Nam");
+        assert_eq!(s.slice_from(0), "abcประเทศไทย中华Việt Nam");
     }
 
     #[test]
@@ -1197,7 +1220,7 @@ fn test_push() {
         data.push('¢'); // 2 byte
         data.push('€'); // 3 byte
         data.push('𤭢'); // 4 byte
-        assert_eq!(data.as_slice(), "ประเทศไทย中华b¢€𤭢");
+        assert_eq!(data, "ประเทศไทย中华b¢€𤭢");
     }
 
     #[test]
@@ -1208,24 +1231,24 @@ fn test_pop() {
         assert_eq!(data.pop().unwrap(), '¢'); // 2 bytes
         assert_eq!(data.pop().unwrap(), 'b'); // 1 bytes
         assert_eq!(data.pop().unwrap(), '华');
-        assert_eq!(data.as_slice(), "ประเทศไทย中");
+        assert_eq!(data, "ประเทศไทย中");
     }
 
     #[test]
     fn test_str_truncate() {
         let mut s = String::from_str("12345");
         s.truncate(5);
-        assert_eq!(s.as_slice(), "12345");
+        assert_eq!(s, "12345");
         s.truncate(3);
-        assert_eq!(s.as_slice(), "123");
+        assert_eq!(s, "123");
         s.truncate(0);
-        assert_eq!(s.as_slice(), "");
+        assert_eq!(s, "");
 
         let mut s = String::from_str("12345");
-        let p = s.as_slice().as_ptr();
+        let p = s.as_ptr();
         s.truncate(3);
         s.push_str("6");
-        let p_ = s.as_slice().as_ptr();
+        let p_ = s.as_ptr();
         assert_eq!(p_, p);
     }
 
@@ -1248,7 +1271,7 @@ fn test_str_clear() {
         let mut s = String::from_str("12345");
         s.clear();
         assert_eq!(s.len(), 0);
-        assert_eq!(s.as_slice(), "");
+        assert_eq!(s, "");
     }
 
     #[test]
@@ -1257,7 +1280,7 @@ fn test_str_add() {
         let b = a + "2";
         let b = b + String::from_str("2");
         assert_eq!(b.len(), 7);
-        assert_eq!(b.as_slice(), "1234522");
+        assert_eq!(b, "1234522");
     }
 
     #[test]
@@ -1265,11 +1288,11 @@ fn remove() {
         let mut s = "ศไทย中华Việt Nam; foobar".to_string();;
         assert_eq!(s.remove(0), Some('ศ'));
         assert_eq!(s.len(), 33);
-        assert_eq!(s.as_slice(), "ไทย中华Việt Nam; foobar");
+        assert_eq!(s, "ไทย中华Việt Nam; foobar");
         assert_eq!(s.remove(33), None);
         assert_eq!(s.remove(300), None);
         assert_eq!(s.remove(17), Some('ệ'));
-        assert_eq!(s.as_slice(), "ไทย中华Vit Nam; foobar");
+        assert_eq!(s, "ไทย中华Vit Nam; foobar");
     }
 
     #[test] #[should_fail]
@@ -1281,9 +1304,9 @@ fn remove_bad() {
     fn insert() {
         let mut s = "foobar".to_string();
         s.insert(0, 'ệ');
-        assert_eq!(s.as_slice(), "ệfoobar");
+        assert_eq!(s, "ệfoobar");
         s.insert(6, 'ย');
-        assert_eq!(s.as_slice(), "ệfooยbar");
+        assert_eq!(s, "ệfooยbar");
     }
 
     #[test] #[should_fail] fn insert_bad1() { "".to_string().insert(1, 't'); }
@@ -1300,24 +1323,45 @@ fn test_slicing() {
 
     #[test]
     fn test_simple_types() {
-        assert_eq!(1i.to_string(), "1".to_string());
-        assert_eq!((-1i).to_string(), "-1".to_string());
-        assert_eq!(200u.to_string(), "200".to_string());
-        assert_eq!(2u8.to_string(), "2".to_string());
-        assert_eq!(true.to_string(), "true".to_string());
-        assert_eq!(false.to_string(), "false".to_string());
-        assert_eq!(().to_string(), "()".to_string());
-        assert_eq!(("hi".to_string()).to_string(), "hi".to_string());
+        assert_eq!(1i.to_string(), "1");
+        assert_eq!((-1i).to_string(), "-1");
+        assert_eq!(200u.to_string(), "200");
+        assert_eq!(2u8.to_string(), "2");
+        assert_eq!(true.to_string(), "true");
+        assert_eq!(false.to_string(), "false");
+        assert_eq!(().to_string(), "()");
+        assert_eq!(("hi".to_string()).to_string(), "hi");
     }
 
     #[test]
     fn test_vectors() {
         let x: Vec<int> = vec![];
-        assert_eq!(x.to_string(), "[]".to_string());
-        assert_eq!((vec![1i]).to_string(), "[1]".to_string());
-        assert_eq!((vec![1i, 2, 3]).to_string(), "[1, 2, 3]".to_string());
+        assert_eq!(x.to_string(), "[]");
+        assert_eq!((vec![1i]).to_string(), "[1]");
+        assert_eq!((vec![1i, 2, 3]).to_string(), "[1, 2, 3]");
         assert!((vec![vec![], vec![1i], vec![1i, 1]]).to_string() ==
-               "[[], [1], [1, 1]]".to_string());
+               "[[], [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]
index 119268c27eeac9814637396c4481a2af7240c269..3818be5a19791e6e1fe53f56399556536bb477ac 100644 (file)
@@ -1735,8 +1735,8 @@ fn test_show() {
 
         let map_str = format!("{}", map);
 
-        assert!(map_str == "{1: 2, 3: 4}".to_string());
-        assert_eq!(format!("{}", empty), "{}".to_string());
+        assert!(map_str == "{1: 2, 3: 4}");
+        assert_eq!(format!("{}", empty), "{}");
     }
 
     #[test]
index 6988b929df689ef3b1d259ab5c7fe22bda90f574..15bf4988619cc24a6bbd806ae7b7bdec924cdeae 100644 (file)
@@ -21,7 +21,6 @@
 use tree_map::{TreeMap, Entries, RevEntries, MoveEntries};
 
 // FIXME(conventions): implement bounded iterators
-// FIXME(conventions): implement BitOr, BitAnd, BitXor, and Sub
 // FIXME(conventions): replace rev_iter(_mut) by making iter(_mut) DoubleEnded
 
 /// An implementation of the `Set` trait on top of the `TreeMap` container. The
@@ -666,6 +665,90 @@ fn next(&mut self) -> Option<&'a T> {
     }
 }
 
+#[unstable = "matches collection reform specification, waiting for dust to settle"]
+impl<T: Ord + Clone> BitOr<TreeSet<T>, TreeSet<T>> for TreeSet<T> {
+    /// Returns the union of `self` and `rhs` as a new `TreeSet<T>`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TreeSet;
+    ///
+    /// let a: TreeSet<int> = vec![1, 2, 3].into_iter().collect();
+    /// let b: TreeSet<int> = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set: TreeSet<int> = a | b;
+    /// let v: Vec<int> = set.into_iter().collect();
+    /// assert_eq!(v, vec![1, 2, 3, 4, 5]);
+    /// ```
+    fn bitor(&self, rhs: &TreeSet<T>) -> TreeSet<T> {
+        self.union(rhs).cloned().collect()
+    }
+}
+
+#[unstable = "matches collection reform specification, waiting for dust to settle"]
+impl<T: Ord + Clone> BitAnd<TreeSet<T>, TreeSet<T>> for TreeSet<T> {
+    /// Returns the intersection of `self` and `rhs` as a new `TreeSet<T>`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TreeSet;
+    ///
+    /// let a: TreeSet<int> = vec![1, 2, 3].into_iter().collect();
+    /// let b: TreeSet<int> = vec![2, 3, 4].into_iter().collect();
+    ///
+    /// let set: TreeSet<int> = a & b;
+    /// let v: Vec<int> = set.into_iter().collect();
+    /// assert_eq!(v, vec![2, 3]);
+    /// ```
+    fn bitand(&self, rhs: &TreeSet<T>) -> TreeSet<T> {
+        self.intersection(rhs).cloned().collect()
+    }
+}
+
+#[unstable = "matches collection reform specification, waiting for dust to settle"]
+impl<T: Ord + Clone> BitXor<TreeSet<T>, TreeSet<T>> for TreeSet<T> {
+    /// Returns the symmetric difference of `self` and `rhs` as a new `TreeSet<T>`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TreeSet;
+    ///
+    /// let a: TreeSet<int> = vec![1, 2, 3].into_iter().collect();
+    /// let b: TreeSet<int> = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set: TreeSet<int> = a ^ b;
+    /// let v: Vec<int> = set.into_iter().collect();
+    /// assert_eq!(v, vec![1, 2, 4, 5]);
+    /// ```
+    fn bitxor(&self, rhs: &TreeSet<T>) -> TreeSet<T> {
+        self.symmetric_difference(rhs).cloned().collect()
+    }
+}
+
+#[unstable = "matches collection reform specification, waiting for dust to settle"]
+impl<T: Ord + Clone> Sub<TreeSet<T>, TreeSet<T>> for TreeSet<T> {
+    /// Returns the difference of `self` and `rhs` as a new `TreeSet<T>`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TreeSet;
+    ///
+    /// let a: TreeSet<int> = vec![1, 2, 3].into_iter().collect();
+    /// let b: TreeSet<int> = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set: TreeSet<int> = a - b;
+    /// let v: Vec<int> = set.into_iter().collect();
+    /// assert_eq!(v, vec![1, 2]);
+    /// ```
+    fn sub(&self, rhs: &TreeSet<T>) -> TreeSet<T> {
+        self.difference(rhs).cloned().collect()
+    }
+}
+
 impl<T: Ord> FromIterator<T> for TreeSet<T> {
     fn from_iter<Iter: Iterator<T>>(iter: Iter) -> TreeSet<T> {
         let mut set = TreeSet::new();
@@ -695,6 +778,7 @@ fn hash(&self, state: &mut S) {
 mod test {
     use std::prelude::*;
     use std::hash;
+    use vec::Vec;
 
     use super::TreeSet;
 
@@ -932,6 +1016,46 @@ fn check_union(a: &[int], b: &[int],
                     &[-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]);
     }
 
+    #[test]
+    fn test_bit_or() {
+        let a: TreeSet<int> = vec![1, 3, 5, 9, 11, 16, 19, 24].into_iter().collect();
+        let b: TreeSet<int> = vec![-2, 1, 5, 9, 13, 19].into_iter().collect();
+
+        let set: TreeSet<int> = a | b;
+        let v: Vec<int> = set.into_iter().collect();
+        assert_eq!(v, vec![-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]);
+    }
+
+    #[test]
+    fn test_bit_and() {
+        let a: TreeSet<int> = vec![11, 1, 3, 77, 103, 5, -5].into_iter().collect();
+        let b: TreeSet<int> = vec![2, 11, 77, -9, -42, 5, 3].into_iter().collect();
+
+        let set: TreeSet<int> = a & b;
+        let v: Vec<int> = set.into_iter().collect();
+        assert_eq!(v, vec![3, 5, 11, 77]);
+    }
+
+    #[test]
+    fn test_bit_xor() {
+        let a: TreeSet<int> = vec![1, 3, 5, 9, 11].into_iter().collect();
+        let b: TreeSet<int> = vec![-2, 3, 9, 14, 22].into_iter().collect();
+
+        let set: TreeSet<int> = a ^ b;
+        let v: Vec<int> = set.into_iter().collect();
+        assert_eq!(v, vec![-2, 1, 5, 11, 14, 22]);
+    }
+
+    #[test]
+    fn test_sub() {
+        let a: TreeSet<int> = vec![-5, 11, 22, 33, 40, 42].into_iter().collect();
+        let b: TreeSet<int> = vec![-12, -5, 14, 23, 34, 38, 39, 50].into_iter().collect();
+
+        let set: TreeSet<int> = a - b;
+        let v: Vec<int> = set.into_iter().collect();
+        assert_eq!(v, vec![11, 22, 33, 40, 42]);
+    }
+
     #[test]
     fn test_zip() {
         let mut x = TreeSet::new();
@@ -979,7 +1103,7 @@ fn test_show() {
 
         let set_str = format!("{}", set);
 
-        assert!(set_str == "{1, 2}".to_string());
-        assert_eq!(format!("{}", empty), "{}".to_string());
+        assert!(set_str == "{1, 2}");
+        assert_eq!(format!("{}", empty), "{}");
     }
 }
index 672ddab4d87e097c875c5723d44388b58f282ecb..6491c9a569dc621486a11819e4efc70159cbee1e 100644 (file)
@@ -1605,8 +1605,8 @@ fn test_show() {
 
         let map_str = format!("{}", map);
 
-        assert!(map_str == "{1: a, 2: b}".to_string());
-        assert_eq!(format!("{}", empty), "{}".to_string());
+        assert!(map_str == "{1: a, 2: b}");
+        assert_eq!(format!("{}", empty), "{}");
     }
 
     #[test]
index 1b3657943da6dbad8765c03a668a7ead9fb2ec54..436da51174284d9aedbe40a87beae96de79c0bfb 100644 (file)
@@ -696,8 +696,8 @@ fn test_show() {
 
         let set_str = format!("{}", set);
 
-        assert!(set_str == "{1, 2}".to_string());
-        assert_eq!(format!("{}", empty), "{}".to_string());
+        assert!(set_str == "{1, 2}");
+        assert_eq!(format!("{}", empty), "{}");
     }
 
     #[test]
index 2396cf8cec67ce20d235031f3a44e8888728b2c7..1509306bbf5c3af7cdb115e6fa00cef3a6da1547 100644 (file)
@@ -211,22 +211,16 @@ pub fn from_fn(length: uint, op: |uint| -> T) -> Vec<T> {
             let mut xs = Vec::with_capacity(length);
             while xs.len < length {
                 let len = xs.len;
-                ptr::write(xs.as_mut_slice().unsafe_mut(len), op(len));
+                ptr::write(xs.unsafe_mut(len), op(len));
                 xs.len += 1;
             }
             xs
         }
     }
 
-    /// Creates a `Vec<T>` directly from the raw constituents.
+    /// Creates a `Vec<T>` directly from the raw components of another vector.
     ///
-    /// This is highly unsafe:
-    ///
-    /// - if `ptr` is null, then `length` and `capacity` should be 0
-    /// - `ptr` must point to an allocation of size `capacity`
-    /// - there must be `length` valid instances of type `T` at the
-    ///   beginning of that allocation
-    /// - `ptr` must be allocated by the default `Vec` allocator
+    /// This is highly unsafe, due to the number of invariants that aren't checked.
     ///
     /// # Example
     ///
@@ -328,7 +322,7 @@ pub fn from_elem(length: uint, value: T) -> Vec<T> {
             let mut xs = Vec::with_capacity(length);
             while xs.len < length {
                 let len = xs.len;
-                ptr::write(xs.as_mut_slice().unsafe_mut(len),
+                ptr::write(xs.unsafe_mut(len),
                            value.clone());
                 xs.len += 1;
             }
@@ -361,7 +355,7 @@ pub fn push_all(&mut self, other: &[T]) {
             // during the loop can prevent this optimisation.
             unsafe {
                 ptr::write(
-                    self.as_mut_slice().unsafe_mut(len),
+                    self.unsafe_mut(len),
                     other.unsafe_get(i).clone());
                 self.set_len(len + 1);
             }
@@ -688,11 +682,12 @@ pub fn reserve(&mut self, additional: uint) {
                 Some(new_cap) => {
                     let amort_cap = new_cap.next_power_of_two();
                     // next_power_of_two will overflow to exactly 0 for really big capacities
-                    if amort_cap == 0 {
-                        self.grow_capacity(new_cap);
+                    let cap = if amort_cap == 0 {
+                        new_cap
                     } else {
-                        self.grow_capacity(amort_cap);
-                    }
+                        amort_cap
+                    };
+                    self.grow_capacity(cap)
                 }
             }
         }
@@ -798,7 +793,7 @@ pub fn truncate(&mut self, len: uint) {
                 // decrement len before the read(), so a panic on Drop doesn't
                 // re-drop the just-failed value.
                 self.len -= 1;
-                ptr::read(self.as_slice().unsafe_get(self.len));
+                ptr::read(self.unsafe_get(self.len));
             }
         }
     }
@@ -896,7 +891,7 @@ pub unsafe fn set_len(&mut self, len: uint) {
     pub fn swap_remove(&mut self, index: uint) -> Option<T> {
         let length = self.len();
         if length > 0 && index < length - 1 {
-            self.as_mut_slice().swap(index, length - 1);
+            self.swap(index, length - 1);
         } else if index >= length {
             return None
         }
@@ -1091,7 +1086,7 @@ pub fn pop(&mut self) -> Option<T> {
         } else {
             unsafe {
                 self.len -= 1;
-                Some(ptr::read(self.as_slice().unsafe_get(self.len())))
+                Some(ptr::read(self.unsafe_get(self.len())))
             }
         }
     }
@@ -1231,7 +1226,7 @@ pub fn dedup(&mut self) {
             if ln < 1 { return; }
 
             // Avoid bounds checks by using unsafe pointers.
-            let p = self.as_mut_slice().as_mut_ptr();
+            let p = self.as_mut_ptr();
             let mut r = 1;
             let mut w = 1;
 
@@ -1293,7 +1288,7 @@ fn drop(&mut self) {
         // zeroed (when moving out, because of #[unsafe_no_drop_flag]).
         if self.cap != 0 {
             unsafe {
-                for x in self.as_mut_slice().iter() {
+                for x in self.iter() {
                     ptr::read(x);
                 }
                 dealloc(self.ptr, self.cap)
@@ -1779,7 +1774,7 @@ fn drop(&mut self) {
     #[test]
     fn test_as_vec() {
         let xs = [1u8, 2u8, 3u8];
-        assert_eq!(as_vec(&xs).as_slice(), xs.as_slice());
+        assert_eq!(as_vec(&xs).as_slice(), xs);
     }
 
     #[test]
@@ -1875,7 +1870,7 @@ fn test_slice_from_mut() {
             }
         }
 
-        assert!(values.as_slice() == [1, 2, 5, 6, 7]);
+        assert!(values == [1, 2, 5, 6, 7]);
     }
 
     #[test]
@@ -1889,7 +1884,7 @@ fn test_slice_to_mut() {
             }
         }
 
-        assert!(values.as_slice() == [2, 3, 3, 4, 5]);
+        assert!(values == [2, 3, 3, 4, 5]);
     }
 
     #[test]
@@ -2019,7 +2014,6 @@ fn test_zip_unzip() {
 
         let (left, right) = unzip(z1.iter().map(|&x| x));
 
-        let (left, right) = (left.as_slice(), right.as_slice());
         assert_eq!((1, 4), (left[0], right[0]));
         assert_eq!((2, 5), (left[1], right[1]));
         assert_eq!((3, 6), (left[2], right[2]));
@@ -2153,7 +2147,7 @@ fn test_map_in_place_incompatible_types_fail() {
     #[test]
     fn test_map_in_place() {
         let v = vec![0u, 1, 2];
-        assert_eq!(v.map_in_place(|i: uint| i as int - 1).as_slice(), [-1i, 0, 1].as_slice());
+        assert_eq!(v.map_in_place(|i: uint| i as int - 1), [-1i, 0, 1]);
     }
 
     #[test]
@@ -2161,7 +2155,7 @@ fn test_map_in_place_zero_sized() {
         let v = vec![(), ()];
         #[deriving(PartialEq, Show)]
         struct ZeroSized;
-        assert_eq!(v.map_in_place(|_| ZeroSized).as_slice(), [ZeroSized, ZeroSized].as_slice());
+        assert_eq!(v.map_in_place(|_| ZeroSized), [ZeroSized, ZeroSized]);
     }
 
     #[test]
@@ -2198,7 +2192,7 @@ fn test_move_items_zero_sized() {
     fn test_into_boxed_slice() {
         let xs = vec![1u, 2, 3];
         let ys = xs.into_boxed_slice();
-        assert_eq!(ys.as_slice(), [1u, 2, 3].as_slice());
+        assert_eq!(ys.as_slice(), [1u, 2, 3]);
     }
 
     #[bench]
index 986e7ef5bc24e9d7d4e97de79ec32cc4bc511a67..97b80108d766ef6c60dd72d88dee162f99d9442b 100644 (file)
@@ -870,9 +870,8 @@ fn test_show() {
         map.insert(3, 4i);
 
         let map_str = map.to_string();
-        let map_str = map_str.as_slice();
         assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}");
-        assert_eq!(format!("{}", empty), "{}".to_string());
+        assert_eq!(format!("{}", empty), "{}");
     }
 
     #[test]
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 9b67cdd3e1275dd1a3dfe5eb75075a3c89115c48..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
@@ -92,6 +94,9 @@ pub struct Formatter<'a> {
     args: &'a [Argument<'a>],
 }
 
+// NB. Argument is essentially an optimized partially applied formatting function,
+// equivalent to `exists T.(&T, fn(&T, &mut Formatter) -> Result`.
+
 enum Void {}
 
 /// This struct represents the generic "argument" which is taken by the Xprintf
@@ -100,21 +105,49 @@ enum Void {}
 /// types, and then this struct is used to canonicalize arguments to one type.
 #[experimental = "implementation detail of the `format_args!` macro"]
 pub struct Argument<'a> {
-    formatter: extern "Rust" fn(&Void, &mut Formatter) -> Result,
     value: &'a Void,
+    formatter: fn(&Void, &mut Formatter) -> Result,
 }
 
+impl<'a> Argument<'a> {
+    #[inline(never)]
+    fn show_uint(x: &uint, f: &mut Formatter) -> Result {
+        Show::fmt(x, f)
+    }
+
+    fn new<'a, T>(x: &'a T, f: fn(&T, &mut Formatter) -> Result) -> Argument<'a> {
+        unsafe {
+            Argument {
+                formatter: mem::transmute(f),
+                value: mem::transmute(x)
+            }
+        }
+    }
+
+    fn from_uint<'a>(x: &'a uint) -> Argument<'a> {
+        Argument::new(x, Argument::show_uint)
+    }
+
+    fn as_uint(&self) -> Option<uint> {
+        if self.formatter as uint == Argument::show_uint as uint {
+            Some(unsafe { *(self.value as *const _ as *const uint) })
+        } else {
+            None
+        }
+    }
+}
+
+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. The compiler inserts an `unsafe` block to call this,
-    /// which is valid because the compiler performs all necessary validation to
-    /// ensure that the resulting call to format/write would be safe.
+    /// Arguments structure.
     #[doc(hidden)] #[inline]
     #[experimental = "implementation detail of the `format_args!` macro"]
-    pub unsafe fn new<'a>(pieces: &'static [&'static str],
-                          args: &'a [Argument<'a>]) -> Arguments<'a> {
+    pub fn new<'a>(pieces: &'a [&'a str],
+                   args: &'a [Argument<'a>]) -> Arguments<'a> {
         Arguments {
-            pieces: mem::transmute(pieces),
+            pieces: pieces,
             fmt: None,
             args: args
         }
@@ -122,15 +155,18 @@ pub unsafe fn new<'a>(pieces: &'static [&'static str],
 
     /// This function is used to specify nonstandard formatting parameters.
     /// The `pieces` array must be at least as long as `fmt` to construct
-    /// a valid Arguments structure.
+    /// a valid Arguments structure. Also, any `Count` within `fmt` that is
+    /// `CountIsParam` or `CountIsNextParam` has to point to an argument
+    /// created with `argumentuint`. However, failing to do so doesn't cause
+    /// unsafety, but will ignore invalid .
     #[doc(hidden)] #[inline]
     #[experimental = "implementation detail of the `format_args!` macro"]
-    pub unsafe fn with_placeholders<'a>(pieces: &'static [&'static str],
-                                        fmt: &'static [rt::Argument<'static>],
-                                        args: &'a [Argument<'a>]) -> Arguments<'a> {
+    pub fn with_placeholders<'a>(pieces: &'a [&'a str],
+                                 fmt: &'a [rt::Argument<'a>],
+                                 args: &'a [Argument<'a>]) -> Arguments<'a> {
         Arguments {
-            pieces: mem::transmute(pieces),
-            fmt: Some(mem::transmute(fmt)),
+            pieces: pieces,
+            fmt: Some(fmt),
             args: args
         }
     }
@@ -312,15 +348,13 @@ fn run(&mut self, arg: &rt::Argument) -> Result {
 
     fn getcount(&mut self, cnt: &rt::Count) -> Option<uint> {
         match *cnt {
-            rt::CountIs(n) => { Some(n) }
-            rt::CountImplied => { None }
+            rt::CountIs(n) => Some(n),
+            rt::CountImplied => None,
             rt::CountIsParam(i) => {
-                let v = self.args[i].value;
-                unsafe { Some(*(v as *const _ as *const uint)) }
+                self.args[i].as_uint()
             }
             rt::CountIsNextParam => {
-                let v = self.curarg.next().unwrap().value;
-                unsafe { Some(*(v as *const _ as *const uint)) }
+                self.curarg.next().and_then(|arg| arg.as_uint())
             }
         }
     }
@@ -533,30 +567,17 @@ fn fmt(&self, f: &mut Formatter) -> Result {
 /// create the Argument structures that are passed into the `format` function.
 #[doc(hidden)] #[inline]
 #[experimental = "implementation detail of the `format_args!` macro"]
-pub fn argument<'a, T>(f: extern "Rust" fn(&T, &mut Formatter) -> Result,
+pub fn argument<'a, T>(f: fn(&T, &mut Formatter) -> Result,
                        t: &'a T) -> Argument<'a> {
-    unsafe {
-        Argument {
-            formatter: mem::transmute(f),
-            value: mem::transmute(t)
-        }
-    }
-}
-
-/// When the compiler determines that the type of an argument *must* be a string
-/// (such as for select), then it invokes this method.
-#[doc(hidden)] #[inline]
-#[experimental = "implementation detail of the `format_args!` macro"]
-pub fn argumentstr<'a>(s: &'a &str) -> Argument<'a> {
-    argument(Show::fmt, s)
+    Argument::new(t, f)
 }
 
 /// When the compiler determines that the type of an argument *must* be a uint
-/// (such as for plural), then it invokes this method.
+/// (such as for width and precision), then it invokes this method.
 #[doc(hidden)] #[inline]
 #[experimental = "implementation detail of the `format_args!` macro"]
 pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> {
-    argument(Show::fmt, s)
+    Argument::from_uint(s)
 }
 
 // Implementations of the core formatting traits
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 6444cf7ee0ebfea3243d51c23a4c6b32ca69b052..54da6264bb0491e1f947250c7f723c2c73ebe557 100644 (file)
@@ -29,10 +29,10 @@ fn smoketest_cell() {
 #[test]
 fn cell_has_sensible_show() {
     let x = Cell::new("foo bar");
-    assert!(format!("{}", x).as_slice().contains(x.get()));
+    assert!(format!("{}", x).contains(x.get()));
 
     x.set("baz qux");
-    assert!(format!("{}", x).as_slice().contains(x.get()));
+    assert!(format!("{}", x).contains(x.get()));
 }
 
 #[test]
@@ -40,11 +40,11 @@ fn ref_and_refmut_have_sensible_show() {
     let refcell = RefCell::new("foo");
 
     let refcell_refmut = refcell.borrow_mut();
-    assert!(format!("{}", refcell_refmut).as_slice().contains("foo"));
+    assert!(format!("{}", refcell_refmut).contains("foo"));
     drop(refcell_refmut);
 
     let refcell_ref = refcell.borrow();
-    assert!(format!("{}", refcell_ref).as_slice().contains("foo"));
+    assert!(format!("{}", refcell_ref).contains("foo"));
     drop(refcell_ref);
 }
 
index 507ddf65e55b35c9dca1b4a6d72053bc68620346..e5561bebb22d8927c8fb62e71b9f6095f5c623cb 100644 (file)
@@ -121,31 +121,31 @@ fn string(c: char) -> String {
         return result;
     }
     let s = string('\n');
-    assert_eq!(s.as_slice(), "\\n");
+    assert_eq!(s, "\\n");
     let s = string('\r');
-    assert_eq!(s.as_slice(), "\\r");
+    assert_eq!(s, "\\r");
     let s = string('\'');
-    assert_eq!(s.as_slice(), "\\'");
+    assert_eq!(s, "\\'");
     let s = string('"');
-    assert_eq!(s.as_slice(), "\\\"");
+    assert_eq!(s, "\\\"");
     let s = string(' ');
-    assert_eq!(s.as_slice(), " ");
+    assert_eq!(s, " ");
     let s = string('a');
-    assert_eq!(s.as_slice(), "a");
+    assert_eq!(s, "a");
     let s = string('~');
-    assert_eq!(s.as_slice(), "~");
+    assert_eq!(s, "~");
     let s = string('\x00');
-    assert_eq!(s.as_slice(), "\\x00");
+    assert_eq!(s, "\\x00");
     let s = string('\x1f');
-    assert_eq!(s.as_slice(), "\\x1f");
+    assert_eq!(s, "\\x1f");
     let s = string('\x7f');
-    assert_eq!(s.as_slice(), "\\x7f");
+    assert_eq!(s, "\\x7f");
     let s = string('\u00ff');
-    assert_eq!(s.as_slice(), "\\u00ff");
+    assert_eq!(s, "\\u00ff");
     let s = string('\u011b');
-    assert_eq!(s.as_slice(), "\\u011b");
+    assert_eq!(s, "\\u011b");
     let s = string('\U0001d4b6');
-    assert_eq!(s.as_slice(), "\\U0001d4b6");
+    assert_eq!(s, "\\U0001d4b6");
 }
 
 #[test]
@@ -156,17 +156,17 @@ fn string(c: char) -> String {
         return result;
     }
     let s = string('\x00');
-    assert_eq!(s.as_slice(), "\\x00");
+    assert_eq!(s, "\\x00");
     let s = string('\n');
-    assert_eq!(s.as_slice(), "\\x0a");
+    assert_eq!(s, "\\x0a");
     let s = string(' ');
-    assert_eq!(s.as_slice(), "\\x20");
+    assert_eq!(s, "\\x20");
     let s = string('a');
-    assert_eq!(s.as_slice(), "\\x61");
+    assert_eq!(s, "\\x61");
     let s = string('\u011b');
-    assert_eq!(s.as_slice(), "\\u011b");
+    assert_eq!(s, "\\u011b");
     let s = string('\U0001d4b6');
-    assert_eq!(s.as_slice(), "\\U0001d4b6");
+    assert_eq!(s, "\\U0001d4b6");
 }
 
 #[test]
index 3b43d6ad33b4429c4b6b210938a2da05891eb020..1e28933becd6ec6808011712ca09e77f76aac57d 100644 (file)
@@ -16,136 +16,136 @@ fn test_format_int() {
     // Formatting integers should select the right implementation based off
     // the type of the argument. Also, hex/octal/binary should be defined
     // for integers, but they shouldn't emit the negative sign.
-    assert!(format!("{}", 1i).as_slice() == "1");
-    assert!(format!("{}", 1i8).as_slice() == "1");
-    assert!(format!("{}", 1i16).as_slice() == "1");
-    assert!(format!("{}", 1i32).as_slice() == "1");
-    assert!(format!("{}", 1i64).as_slice() == "1");
-    assert!(format!("{}", -1i).as_slice() == "-1");
-    assert!(format!("{}", -1i8).as_slice() == "-1");
-    assert!(format!("{}", -1i16).as_slice() == "-1");
-    assert!(format!("{}", -1i32).as_slice() == "-1");
-    assert!(format!("{}", -1i64).as_slice() == "-1");
-    assert!(format!("{:b}", 1i).as_slice() == "1");
-    assert!(format!("{:b}", 1i8).as_slice() == "1");
-    assert!(format!("{:b}", 1i16).as_slice() == "1");
-    assert!(format!("{:b}", 1i32).as_slice() == "1");
-    assert!(format!("{:b}", 1i64).as_slice() == "1");
-    assert!(format!("{:x}", 1i).as_slice() == "1");
-    assert!(format!("{:x}", 1i8).as_slice() == "1");
-    assert!(format!("{:x}", 1i16).as_slice() == "1");
-    assert!(format!("{:x}", 1i32).as_slice() == "1");
-    assert!(format!("{:x}", 1i64).as_slice() == "1");
-    assert!(format!("{:X}", 1i).as_slice() == "1");
-    assert!(format!("{:X}", 1i8).as_slice() == "1");
-    assert!(format!("{:X}", 1i16).as_slice() == "1");
-    assert!(format!("{:X}", 1i32).as_slice() == "1");
-    assert!(format!("{:X}", 1i64).as_slice() == "1");
-    assert!(format!("{:o}", 1i).as_slice() == "1");
-    assert!(format!("{:o}", 1i8).as_slice() == "1");
-    assert!(format!("{:o}", 1i16).as_slice() == "1");
-    assert!(format!("{:o}", 1i32).as_slice() == "1");
-    assert!(format!("{:o}", 1i64).as_slice() == "1");
-
-    assert!(format!("{}", 1u).as_slice() == "1");
-    assert!(format!("{}", 1u8).as_slice() == "1");
-    assert!(format!("{}", 1u16).as_slice() == "1");
-    assert!(format!("{}", 1u32).as_slice() == "1");
-    assert!(format!("{}", 1u64).as_slice() == "1");
-    assert!(format!("{:b}", 1u).as_slice() == "1");
-    assert!(format!("{:b}", 1u8).as_slice() == "1");
-    assert!(format!("{:b}", 1u16).as_slice() == "1");
-    assert!(format!("{:b}", 1u32).as_slice() == "1");
-    assert!(format!("{:b}", 1u64).as_slice() == "1");
-    assert!(format!("{:x}", 1u).as_slice() == "1");
-    assert!(format!("{:x}", 1u8).as_slice() == "1");
-    assert!(format!("{:x}", 1u16).as_slice() == "1");
-    assert!(format!("{:x}", 1u32).as_slice() == "1");
-    assert!(format!("{:x}", 1u64).as_slice() == "1");
-    assert!(format!("{:X}", 1u).as_slice() == "1");
-    assert!(format!("{:X}", 1u8).as_slice() == "1");
-    assert!(format!("{:X}", 1u16).as_slice() == "1");
-    assert!(format!("{:X}", 1u32).as_slice() == "1");
-    assert!(format!("{:X}", 1u64).as_slice() == "1");
-    assert!(format!("{:o}", 1u).as_slice() == "1");
-    assert!(format!("{:o}", 1u8).as_slice() == "1");
-    assert!(format!("{:o}", 1u16).as_slice() == "1");
-    assert!(format!("{:o}", 1u32).as_slice() == "1");
-    assert!(format!("{:o}", 1u64).as_slice() == "1");
+    assert!(format!("{}", 1i) == "1");
+    assert!(format!("{}", 1i8) == "1");
+    assert!(format!("{}", 1i16) == "1");
+    assert!(format!("{}", 1i32) == "1");
+    assert!(format!("{}", 1i64) == "1");
+    assert!(format!("{}", -1i) == "-1");
+    assert!(format!("{}", -1i8) == "-1");
+    assert!(format!("{}", -1i16) == "-1");
+    assert!(format!("{}", -1i32) == "-1");
+    assert!(format!("{}", -1i64) == "-1");
+    assert!(format!("{:b}", 1i) == "1");
+    assert!(format!("{:b}", 1i8) == "1");
+    assert!(format!("{:b}", 1i16) == "1");
+    assert!(format!("{:b}", 1i32) == "1");
+    assert!(format!("{:b}", 1i64) == "1");
+    assert!(format!("{:x}", 1i) == "1");
+    assert!(format!("{:x}", 1i8) == "1");
+    assert!(format!("{:x}", 1i16) == "1");
+    assert!(format!("{:x}", 1i32) == "1");
+    assert!(format!("{:x}", 1i64) == "1");
+    assert!(format!("{:X}", 1i) == "1");
+    assert!(format!("{:X}", 1i8) == "1");
+    assert!(format!("{:X}", 1i16) == "1");
+    assert!(format!("{:X}", 1i32) == "1");
+    assert!(format!("{:X}", 1i64) == "1");
+    assert!(format!("{:o}", 1i) == "1");
+    assert!(format!("{:o}", 1i8) == "1");
+    assert!(format!("{:o}", 1i16) == "1");
+    assert!(format!("{:o}", 1i32) == "1");
+    assert!(format!("{:o}", 1i64) == "1");
+
+    assert!(format!("{}", 1u) == "1");
+    assert!(format!("{}", 1u8) == "1");
+    assert!(format!("{}", 1u16) == "1");
+    assert!(format!("{}", 1u32) == "1");
+    assert!(format!("{}", 1u64) == "1");
+    assert!(format!("{:b}", 1u) == "1");
+    assert!(format!("{:b}", 1u8) == "1");
+    assert!(format!("{:b}", 1u16) == "1");
+    assert!(format!("{:b}", 1u32) == "1");
+    assert!(format!("{:b}", 1u64) == "1");
+    assert!(format!("{:x}", 1u) == "1");
+    assert!(format!("{:x}", 1u8) == "1");
+    assert!(format!("{:x}", 1u16) == "1");
+    assert!(format!("{:x}", 1u32) == "1");
+    assert!(format!("{:x}", 1u64) == "1");
+    assert!(format!("{:X}", 1u) == "1");
+    assert!(format!("{:X}", 1u8) == "1");
+    assert!(format!("{:X}", 1u16) == "1");
+    assert!(format!("{:X}", 1u32) == "1");
+    assert!(format!("{:X}", 1u64) == "1");
+    assert!(format!("{:o}", 1u) == "1");
+    assert!(format!("{:o}", 1u8) == "1");
+    assert!(format!("{:o}", 1u16) == "1");
+    assert!(format!("{:o}", 1u32) == "1");
+    assert!(format!("{:o}", 1u64) == "1");
 
     // Test a larger number
-    assert!(format!("{:b}", 55i).as_slice() == "110111");
-    assert!(format!("{:o}", 55i).as_slice() == "67");
-    assert!(format!("{}", 55i).as_slice() == "55");
-    assert!(format!("{:x}", 55i).as_slice() == "37");
-    assert!(format!("{:X}", 55i).as_slice() == "37");
+    assert!(format!("{:b}", 55i) == "110111");
+    assert!(format!("{:o}", 55i) == "67");
+    assert!(format!("{}", 55i) == "55");
+    assert!(format!("{:x}", 55i) == "37");
+    assert!(format!("{:X}", 55i) == "37");
 }
 
 #[test]
 fn test_format_int_zero() {
-    assert!(format!("{}", 0i).as_slice() == "0");
-    assert!(format!("{:b}", 0i).as_slice() == "0");
-    assert!(format!("{:o}", 0i).as_slice() == "0");
-    assert!(format!("{:x}", 0i).as_slice() == "0");
-    assert!(format!("{:X}", 0i).as_slice() == "0");
-
-    assert!(format!("{}", 0u).as_slice() == "0");
-    assert!(format!("{:b}", 0u).as_slice() == "0");
-    assert!(format!("{:o}", 0u).as_slice() == "0");
-    assert!(format!("{:x}", 0u).as_slice() == "0");
-    assert!(format!("{:X}", 0u).as_slice() == "0");
+    assert!(format!("{}", 0i) == "0");
+    assert!(format!("{:b}", 0i) == "0");
+    assert!(format!("{:o}", 0i) == "0");
+    assert!(format!("{:x}", 0i) == "0");
+    assert!(format!("{:X}", 0i) == "0");
+
+    assert!(format!("{}", 0u) == "0");
+    assert!(format!("{:b}", 0u) == "0");
+    assert!(format!("{:o}", 0u) == "0");
+    assert!(format!("{:x}", 0u) == "0");
+    assert!(format!("{:X}", 0u) == "0");
 }
 
 #[test]
 fn test_format_int_flags() {
-    assert!(format!("{:3}", 1i).as_slice() == "  1");
-    assert!(format!("{:>3}", 1i).as_slice() == "  1");
-    assert!(format!("{:>+3}", 1i).as_slice() == " +1");
-    assert!(format!("{:<3}", 1i).as_slice() == "1  ");
-    assert!(format!("{:#}", 1i).as_slice() == "1");
-    assert!(format!("{:#x}", 10i).as_slice() == "0xa");
-    assert!(format!("{:#X}", 10i).as_slice() == "0xA");
-    assert!(format!("{:#5x}", 10i).as_slice() == "  0xa");
-    assert!(format!("{:#o}", 10i).as_slice() == "0o12");
-    assert!(format!("{:08x}", 10i).as_slice() == "0000000a");
-    assert!(format!("{:8x}", 10i).as_slice() == "       a");
-    assert!(format!("{:<8x}", 10i).as_slice() == "a       ");
-    assert!(format!("{:>8x}", 10i).as_slice() == "       a");
-    assert!(format!("{:#08x}", 10i).as_slice() == "0x00000a");
-    assert!(format!("{:08}", -10i).as_slice() == "-0000010");
-    assert!(format!("{:x}", -1u8).as_slice() == "ff");
-    assert!(format!("{:X}", -1u8).as_slice() == "FF");
-    assert!(format!("{:b}", -1u8).as_slice() == "11111111");
-    assert!(format!("{:o}", -1u8).as_slice() == "377");
-    assert!(format!("{:#x}", -1u8).as_slice() == "0xff");
-    assert!(format!("{:#X}", -1u8).as_slice() == "0xFF");
-    assert!(format!("{:#b}", -1u8).as_slice() == "0b11111111");
-    assert!(format!("{:#o}", -1u8).as_slice() == "0o377");
+    assert!(format!("{:3}", 1i) == "  1");
+    assert!(format!("{:>3}", 1i) == "  1");
+    assert!(format!("{:>+3}", 1i) == " +1");
+    assert!(format!("{:<3}", 1i) == "1  ");
+    assert!(format!("{:#}", 1i) == "1");
+    assert!(format!("{:#x}", 10i) == "0xa");
+    assert!(format!("{:#X}", 10i) == "0xA");
+    assert!(format!("{:#5x}", 10i) == "  0xa");
+    assert!(format!("{:#o}", 10i) == "0o12");
+    assert!(format!("{:08x}", 10i) == "0000000a");
+    assert!(format!("{:8x}", 10i) == "       a");
+    assert!(format!("{:<8x}", 10i) == "a       ");
+    assert!(format!("{:>8x}", 10i) == "       a");
+    assert!(format!("{:#08x}", 10i) == "0x00000a");
+    assert!(format!("{:08}", -10i) == "-0000010");
+    assert!(format!("{:x}", -1u8) == "ff");
+    assert!(format!("{:X}", -1u8) == "FF");
+    assert!(format!("{:b}", -1u8) == "11111111");
+    assert!(format!("{:o}", -1u8) == "377");
+    assert!(format!("{:#x}", -1u8) == "0xff");
+    assert!(format!("{:#X}", -1u8) == "0xFF");
+    assert!(format!("{:#b}", -1u8) == "0b11111111");
+    assert!(format!("{:#o}", -1u8) == "0o377");
 }
 
 #[test]
 fn test_format_int_sign_padding() {
-    assert!(format!("{:+5}", 1i).as_slice() == "   +1");
-    assert!(format!("{:+5}", -1i).as_slice() == "   -1");
-    assert!(format!("{:05}", 1i).as_slice() == "00001");
-    assert!(format!("{:05}", -1i).as_slice() == "-0001");
-    assert!(format!("{:+05}", 1i).as_slice() == "+0001");
-    assert!(format!("{:+05}", -1i).as_slice() == "-0001");
+    assert!(format!("{:+5}", 1i) == "   +1");
+    assert!(format!("{:+5}", -1i) == "   -1");
+    assert!(format!("{:05}", 1i) == "00001");
+    assert!(format!("{:05}", -1i) == "-0001");
+    assert!(format!("{:+05}", 1i) == "+0001");
+    assert!(format!("{:+05}", -1i) == "-0001");
 }
 
 #[test]
 fn test_format_int_twos_complement() {
     use core::{i8, i16, i32, i64};
-    assert!(format!("{}", i8::MIN).as_slice() == "-128");
-    assert!(format!("{}", i16::MIN).as_slice() == "-32768");
-    assert!(format!("{}", i32::MIN).as_slice() == "-2147483648");
-    assert!(format!("{}", i64::MIN).as_slice() == "-9223372036854775808");
+    assert!(format!("{}", i8::MIN) == "-128");
+    assert!(format!("{}", i16::MIN) == "-32768");
+    assert!(format!("{}", i32::MIN) == "-2147483648");
+    assert!(format!("{}", i64::MIN) == "-9223372036854775808");
 }
 
 #[test]
 fn test_format_radix() {
-    assert!(format!("{:04}", radix(3i, 2)).as_slice() == "0011");
-    assert!(format!("{}", radix(55i, 36)).as_slice() == "1j");
+    assert!(format!("{:04}", radix(3i, 2)) == "0011");
+    assert!(format!("{}", radix(55i, 36)) == "1j");
 }
 
 #[test]
index a5927d47eb0af70b1605fc85e7c6212ba5720d8f..86fc25c9d918c2b765a2fe26645e0ec299668e0e 100644 (file)
@@ -28,10 +28,10 @@ fn test_get_ptr() {
 #[test]
 fn test_get_str() {
     let x = "test".to_string();
-    let addr_x = x.as_slice().as_ptr();
+    let addr_x = x.as_ptr();
     let opt = Some(x);
     let y = opt.unwrap();
-    let addr_y = y.as_slice().as_ptr();
+    let addr_y = y.as_ptr();
     assert_eq!(addr_x, addr_y);
 }
 
@@ -135,7 +135,7 @@ fn test_or_else() {
 fn test_unwrap() {
     assert_eq!(Some(1i).unwrap(), 1);
     let s = Some("hello".to_string()).unwrap();
-    assert_eq!(s.as_slice(), "hello");
+    assert_eq!(s, "hello");
 }
 
 #[test]
@@ -266,4 +266,4 @@ fn test_cloned() {
     assert_eq!(opt_ref_ref.clone(), Some(&val1_ref));
     assert_eq!(opt_ref_ref.clone().cloned(), Some(&val1));
     assert_eq!(opt_ref_ref.cloned().cloned(), Some(1u32));
-}
\ No newline at end of file
+}
index 92124e2f299cd9c730ac793a6e468ca3ef2e8311..415cd4e7dcfb80a75c05be7cf77452d6062bf703 100644 (file)
@@ -93,9 +93,9 @@ pub fn test_fmt_default() {
     let err: Result<int, &'static str> = Err("Err");
 
     let s = format!("{}", ok);
-    assert_eq!(s.as_slice(), "Ok(100)");
+    assert_eq!(s, "Ok(100)");
     let s = format!("{}", err);
-    assert_eq!(s.as_slice(), "Err(Err)");
+    assert_eq!(s, "Err(Err)");
 }
 
 #[test]
index be71e42ae9ad6561af273a2007dd1a218fd82f9a..c53d82de23c6c31a29102cee09fb90ca50ae6fb9 100644 (file)
@@ -84,9 +84,9 @@ fn test_tuple_cmp() {
 #[test]
 fn test_show() {
     let s = format!("{}", (1i,));
-    assert_eq!(s.as_slice(), "(1,)");
+    assert_eq!(s, "(1,)");
     let s = format!("{}", (1i, true));
-    assert_eq!(s.as_slice(), "(1, true)");
+    assert_eq!(s, "(1, true)");
     let s = format!("{}", (1i, "hi", true));
-    assert_eq!(s.as_slice(), "(1, hi, true)");
+    assert_eq!(s, "(1, hi, true)");
 }
index 0318509751bd59dd43e0501c39370fcade0b14a3..cc36c2eef4552e43d2a90d0a9bac92876334098f 100644 (file)
@@ -128,7 +128,7 @@ fn test_flate_round_trip() {
             debug!("{} bytes deflated to {} ({:.1}% size)",
                    input.len(), cmp.len(),
                    100.0 * ((cmp.len() as f64) / (input.len() as f64)));
-            assert_eq!(input.as_slice(), out.as_slice());
+            assert_eq!(input, out.as_slice());
         }
     }
 
@@ -137,6 +137,6 @@ fn test_zlib_flate() {
         let bytes = vec!(1, 2, 3, 4, 5);
         let deflated = deflate_bytes(bytes.as_slice()).expect("deflation failed");
         let inflated = inflate_bytes(deflated.as_slice()).expect("inflation failed");
-        assert_eq!(inflated.as_slice(), bytes.as_slice());
+        assert_eq!(inflated.as_slice(), bytes);
     }
 }
index 03b65b3f71c846de4445f78c0a7f63e824d45119..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.
@@ -440,7 +454,7 @@ mod tests {
 
     fn same(fmt: &'static str, p: &[Piece<'static>]) {
         let mut parser = Parser::new(fmt);
-        assert!(p == parser.collect::<Vec<Piece<'static>>>().as_slice());
+        assert!(p == parser.collect::<Vec<Piece<'static>>>());
     }
 
     fn fmtdflt() -> FormatSpec<'static> {
index e146e3c76eb2f22cb582d7e694e2ccfa8ca4f287..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>;
 
@@ -244,7 +264,7 @@ pub fn long_to_short(&self) -> Opt {
                 aliases: Vec::new()
             },
             (1,0) => Opt {
-                name: Short(short_name.as_slice().char_at(0)),
+                name: Short(short_name.char_at(0)),
                 hasarg: hasarg,
                 occur: occur,
                 aliases: Vec::new()
@@ -255,7 +275,7 @@ pub fn long_to_short(&self) -> Opt {
                 occur: occur,
                 aliases: vec!(
                     Opt {
-                        name: Short(short_name.as_slice().char_at(0)),
+                        name: Short(short_name.char_at(0)),
                         hasarg: hasarg,
                         occur:  occur,
                         aliases: Vec::new()
@@ -576,7 +596,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
         let curlen = cur.len();
         if !is_arg(cur.as_slice()) {
             free.push(cur);
-        } else if cur.as_slice() == "--" {
+        } else if cur == "--" {
             let mut j = i + 1;
             while j < l { free.push(args[j].clone()); j += 1; }
             break;
@@ -584,7 +604,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
             let mut names;
             let mut i_arg = None;
             if cur.as_bytes()[1] == b'-' {
-                let tail = cur.as_slice().slice(2, curlen);
+                let tail = cur.slice(2, curlen);
                 let tail_eq: Vec<&str> = tail.split('=').collect();
                 if tail_eq.len() <= 1 {
                     names = vec!(Long(tail.to_string()));
@@ -597,7 +617,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
                 let mut j = 1;
                 names = Vec::new();
                 while j < curlen {
-                    let range = cur.as_slice().char_range_at(j);
+                    let range = cur.char_range_at(j);
                     let opt = Short(range.ch);
 
                     /* In a series of potential options (eg. -aheJ), if we
@@ -620,8 +640,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
                     };
 
                     if arg_follows && range.next < curlen {
-                        i_arg = Some(cur.as_slice()
-                                        .slice(range.next, curlen).to_string());
+                        i_arg = Some(cur.slice(range.next, curlen).to_string());
                         break;
                     }
 
@@ -736,7 +755,7 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String {
 
         // FIXME: #5516 should be graphemes not codepoints
         // here we just need to indent the start of the description
-        let rowlen = row.as_slice().char_len();
+        let rowlen = row.char_len();
         if rowlen < 24 {
             for _ in range(0, 24 - rowlen) {
                 row.push(' ');
@@ -747,7 +766,7 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String {
 
         // Normalize desc to contain words separated by one space character
         let mut desc_normalized_whitespace = String::new();
-        for word in desc.as_slice().words() {
+        for word in desc.words() {
             desc_normalized_whitespace.push_str(word);
             desc_normalized_whitespace.push(' ');
         }
@@ -825,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,
@@ -848,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;
@@ -963,9 +982,9 @@ fn test_reqopt() {
         match rs {
           Ok(ref m) => {
             assert!(m.opt_present("test"));
-            assert_eq!(m.opt_str("test").unwrap(), "20".to_string());
+            assert_eq!(m.opt_str("test").unwrap(), "20");
             assert!(m.opt_present("t"));
-            assert_eq!(m.opt_str("t").unwrap(), "20".to_string());
+            assert_eq!(m.opt_str("t").unwrap(), "20");
           }
           _ => { panic!("test_reqopt failed (long arg)"); }
         }
@@ -973,9 +992,9 @@ fn test_reqopt() {
         match getopts(short_args.as_slice(), opts.as_slice()) {
           Ok(ref m) => {
             assert!((m.opt_present("test")));
-            assert_eq!(m.opt_str("test").unwrap(), "20".to_string());
+            assert_eq!(m.opt_str("test").unwrap(), "20");
             assert!((m.opt_present("t")));
-            assert_eq!(m.opt_str("t").unwrap(), "20".to_string());
+            assert_eq!(m.opt_str("t").unwrap(), "20");
           }
           _ => { panic!("test_reqopt failed (short arg)"); }
         }
@@ -1028,9 +1047,9 @@ fn test_optopt() {
         match rs {
           Ok(ref m) => {
             assert!(m.opt_present("test"));
-            assert_eq!(m.opt_str("test").unwrap(), "20".to_string());
+            assert_eq!(m.opt_str("test").unwrap(), "20");
             assert!((m.opt_present("t")));
-            assert_eq!(m.opt_str("t").unwrap(), "20".to_string());
+            assert_eq!(m.opt_str("t").unwrap(), "20");
           }
           _ => panic!()
         }
@@ -1038,9 +1057,9 @@ fn test_optopt() {
         match getopts(short_args.as_slice(), opts.as_slice()) {
           Ok(ref m) => {
             assert!((m.opt_present("test")));
-            assert_eq!(m.opt_str("test").unwrap(), "20".to_string());
+            assert_eq!(m.opt_str("test").unwrap(), "20");
             assert!((m.opt_present("t")));
-            assert_eq!(m.opt_str("t").unwrap(), "20".to_string());
+            assert_eq!(m.opt_str("t").unwrap(), "20");
           }
           _ => panic!()
         }
@@ -1155,7 +1174,7 @@ fn test_optflag_short_arg() {
           Ok(ref m) => {
             // The next variable after the flag is just a free argument
 
-            assert!(m.free[0] == "20".to_string());
+            assert!(m.free[0] == "20");
           }
           _ => panic!()
         }
@@ -1251,9 +1270,9 @@ fn test_optmulti() {
         match rs {
           Ok(ref m) => {
             assert!((m.opt_present("test")));
-            assert_eq!(m.opt_str("test").unwrap(), "20".to_string());
+            assert_eq!(m.opt_str("test").unwrap(), "20");
             assert!((m.opt_present("t")));
-            assert_eq!(m.opt_str("t").unwrap(), "20".to_string());
+            assert_eq!(m.opt_str("t").unwrap(), "20");
           }
           _ => panic!()
         }
@@ -1261,9 +1280,9 @@ fn test_optmulti() {
         match getopts(short_args.as_slice(), opts.as_slice()) {
           Ok(ref m) => {
             assert!((m.opt_present("test")));
-            assert_eq!(m.opt_str("test").unwrap(), "20".to_string());
+            assert_eq!(m.opt_str("test").unwrap(), "20");
             assert!((m.opt_present("t")));
-            assert_eq!(m.opt_str("t").unwrap(), "20".to_string());
+            assert_eq!(m.opt_str("t").unwrap(), "20");
           }
           _ => panic!()
         }
@@ -1307,12 +1326,12 @@ fn test_optmulti_multi() {
         match rs {
           Ok(ref m) => {
               assert!(m.opt_present("test"));
-              assert_eq!(m.opt_str("test").unwrap(), "20".to_string());
+              assert_eq!(m.opt_str("test").unwrap(), "20");
               assert!(m.opt_present("t"));
-              assert_eq!(m.opt_str("t").unwrap(), "20".to_string());
+              assert_eq!(m.opt_str("t").unwrap(), "20");
               let pair = m.opt_strs("test");
-              assert!(pair[0] == "20".to_string());
-              assert!(pair[1] == "30".to_string());
+              assert!(pair[0] == "20");
+              assert!(pair[1] == "30");
           }
           _ => panic!()
         }
@@ -1364,19 +1383,19 @@ fn test_combined() {
         let rs = getopts(args.as_slice(), opts.as_slice());
         match rs {
           Ok(ref m) => {
-            assert!(m.free[0] == "prog".to_string());
-            assert!(m.free[1] == "free1".to_string());
-            assert_eq!(m.opt_str("s").unwrap(), "20".to_string());
-            assert!(m.free[2] == "free2".to_string());
+            assert!(m.free[0] == "prog");
+            assert!(m.free[1] == "free1");
+            assert_eq!(m.opt_str("s").unwrap(), "20");
+            assert!(m.free[2] == "free2");
             assert!((m.opt_present("flag")));
-            assert_eq!(m.opt_str("long").unwrap(), "30".to_string());
+            assert_eq!(m.opt_str("long").unwrap(), "30");
             assert!((m.opt_present("f")));
             let pair = m.opt_strs("m");
-            assert!(pair[0] == "40".to_string());
-            assert!(pair[1] == "50".to_string());
+            assert!(pair[0] == "40");
+            assert!(pair[1] == "50");
             let pair = m.opt_strs("n");
-            assert!(pair[0] == "-A B".to_string());
-            assert!(pair[1] == "-60 70".to_string());
+            assert!(pair[0] == "-A B");
+            assert!(pair[1] == "-60 70");
             assert!((!m.opt_present("notpresent")));
           }
           _ => panic!()
@@ -1402,11 +1421,11 @@ fn test_multi() {
         assert!(!matches_single.opts_present(&["thing".to_string()]));
         assert!(!matches_single.opts_present(&[]));
 
-        assert_eq!(matches_single.opts_str(&["e".to_string()]).unwrap(), "foo".to_string());
+        assert_eq!(matches_single.opts_str(&["e".to_string()]).unwrap(), "foo");
         assert_eq!(matches_single.opts_str(&["e".to_string(), "encrypt".to_string()]).unwrap(),
-                   "foo".to_string());
+                   "foo");
         assert_eq!(matches_single.opts_str(&["encrypt".to_string(), "e".to_string()]).unwrap(),
-                   "foo".to_string());
+                   "foo");
 
         let args_both = vec!("-e".to_string(), "foo".to_string(), "--encrypt".to_string(),
                              "foo".to_string());
@@ -1423,12 +1442,12 @@ fn test_multi() {
         assert!(!matches_both.opts_present(&["thing".to_string()]));
         assert!(!matches_both.opts_present(&[]));
 
-        assert_eq!(matches_both.opts_str(&["e".to_string()]).unwrap(), "foo".to_string());
-        assert_eq!(matches_both.opts_str(&["encrypt".to_string()]).unwrap(), "foo".to_string());
+        assert_eq!(matches_both.opts_str(&["e".to_string()]).unwrap(), "foo");
+        assert_eq!(matches_both.opts_str(&["encrypt".to_string()]).unwrap(), "foo");
         assert_eq!(matches_both.opts_str(&["e".to_string(), "encrypt".to_string()]).unwrap(),
-                   "foo".to_string());
+                   "foo");
         assert_eq!(matches_both.opts_str(&["encrypt".to_string(), "e".to_string()]).unwrap(),
-                   "foo".to_string());
+                   "foo");
     }
 
     #[test]
@@ -1441,9 +1460,9 @@ fn test_nospace() {
           result::Result::Err(_) => panic!()
         };
         assert!(matches.opts_present(&["L".to_string()]));
-        assert_eq!(matches.opts_str(&["L".to_string()]).unwrap(), "foo".to_string());
+        assert_eq!(matches.opts_str(&["L".to_string()]).unwrap(), "foo");
         assert!(matches.opts_present(&["M".to_string()]));
-        assert_eq!(matches.opts_str(&["M".to_string()]).unwrap(), ".".to_string());
+        assert_eq!(matches.opts_str(&["M".to_string()]).unwrap(), ".");
 
     }
 
@@ -1457,7 +1476,7 @@ fn test_nospace_conflict() {
           result::Result::Err(e) => panic!( "{}", e )
         };
         assert!(matches.opts_present(&["L".to_string()]));
-        assert_eq!(matches.opts_str(&["L".to_string()]).unwrap(), "verbose".to_string());
+        assert_eq!(matches.opts_str(&["L".to_string()]).unwrap(), "verbose");
         assert!(matches.opts_present(&["v".to_string()]));
         assert_eq!(3, matches.opt_count("v"));
     }
@@ -1511,7 +1530,7 @@ fn test_usage() {
     -k --kiwi           Desc
     -p [VAL]            Desc
     -l VAL              Desc
-".to_string();
+";
 
         let generated_usage = usage("Usage: fruits", optgroups.as_slice());
 
@@ -1538,7 +1557,7 @@ fn test_usage_description_wrapping() {
     -k --kiwi           This is a long description which won't be wrapped..+..
     -a --apple          This is a long description which _will_ be
                         wrapped..+..
-".to_string();
+";
 
         let usage = usage("Usage: fruits", optgroups.as_slice());
 
@@ -1564,7 +1583,7 @@ fn test_usage_description_multibyte_handling() {
     -a --apple          This “description” has some characters that could
                         confuse the line wrapping; an apple costs 0.51€ in
                         some parts of Europe.
-".to_string();
+";
 
         let usage = usage("Usage: fruits", optgroups.as_slice());
 
index 0a5081d07be0072df405b343b1706eaa940a8d97..c1c397db213f64807c88464c4c405e4933540e20 100644 (file)
@@ -439,7 +439,7 @@ fn escape_str(s: &str) -> String {
     /// Renders text as string suitable for a label in a .dot file.
     pub fn escape(&self) -> String {
         match self {
-            &LabelStr(ref s) => s.as_slice().escape_default(),
+            &LabelStr(ref s) => s.escape_default(),
             &EscStr(ref s) => LabelText::escape_str(s.as_slice()),
         }
     }
@@ -709,7 +709,7 @@ fn test_input(g: LabelledGraph) -> IoResult<String> {
     fn empty_graph() {
         let labels : Trivial = UnlabelledNodes(0);
         let r = test_input(LabelledGraph::new("empty_graph", labels, vec!()));
-        assert_eq!(r.unwrap().as_slice(),
+        assert_eq!(r.unwrap(),
 r#"digraph empty_graph {
 }
 "#);
@@ -719,7 +719,7 @@ fn empty_graph() {
     fn single_node() {
         let labels : Trivial = UnlabelledNodes(1);
         let r = test_input(LabelledGraph::new("single_node", labels, vec!()));
-        assert_eq!(r.unwrap().as_slice(),
+        assert_eq!(r.unwrap(),
 r#"digraph single_node {
     N0[label="N0"];
 }
@@ -731,7 +731,7 @@ fn single_edge() {
         let labels : Trivial = UnlabelledNodes(2);
         let result = test_input(LabelledGraph::new("single_edge", labels,
                                                    vec!(edge(0, 1, "E"))));
-        assert_eq!(result.unwrap().as_slice(),
+        assert_eq!(result.unwrap(),
 r#"digraph single_edge {
     N0[label="N0"];
     N1[label="N1"];
@@ -745,7 +745,7 @@ fn test_some_labelled() {
         let labels : Trivial = SomeNodesLabelled(vec![Some("A"), None]);
         let result = test_input(LabelledGraph::new("test_some_labelled", labels,
                                                    vec![edge(0, 1, "A-1")]));
-        assert_eq!(result.unwrap().as_slice(),
+        assert_eq!(result.unwrap(),
 r#"digraph test_some_labelled {
     N0[label="A"];
     N1[label="N1"];
@@ -759,7 +759,7 @@ fn single_cyclic_node() {
         let labels : Trivial = UnlabelledNodes(1);
         let r = test_input(LabelledGraph::new("single_cyclic_node", labels,
                                               vec!(edge(0, 0, "E"))));
-        assert_eq!(r.unwrap().as_slice(),
+        assert_eq!(r.unwrap(),
 r#"digraph single_cyclic_node {
     N0[label="N0"];
     N0 -> N0[label="E"];
@@ -774,7 +774,7 @@ fn hasse_diagram() {
             "hasse_diagram", labels,
             vec!(edge(0, 1, ""), edge(0, 2, ""),
                  edge(1, 3, ""), edge(2, 3, ""))));
-        assert_eq!(r.unwrap().as_slice(),
+        assert_eq!(r.unwrap(),
 r#"digraph hasse_diagram {
     N0[label="{x,y}"];
     N1[label="{x}"];
@@ -812,7 +812,7 @@ fn left_aligned_text() {
         render(&g, &mut writer).unwrap();
         let r = (&mut writer.as_slice()).read_to_string();
 
-        assert_eq!(r.unwrap().as_slice(),
+        assert_eq!(r.unwrap(),
 r#"digraph syntax_tree {
     N0[label="if test {\l    branch1\l} else {\l    branch2\l}\lafterward\l"];
     N1[label="branch1"];
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 a93cf4c15682fd83ef0bfc8cb4ace3c0b8bde85a..d1db0ec89a16bec10112c0ae89114fe5bafa963e 100644 (file)
@@ -100,7 +100,6 @@ mod tests {
     #[test]
     fn parse_logging_spec_valid() {
         let (dirs, filter) = parse_logging_spec("crate1::mod1=1,crate1::mod2,crate2=4");
-        let dirs = dirs.as_slice();
         assert_eq!(dirs.len(), 3);
         assert_eq!(dirs[0].name, Some("crate1::mod1".to_string()));
         assert_eq!(dirs[0].level, 1);
@@ -117,7 +116,6 @@ fn parse_logging_spec_valid() {
     fn parse_logging_spec_invalid_crate() {
         // test parse_logging_spec with multiple = in specification
         let (dirs, filter) = parse_logging_spec("crate1::mod1=1=2,crate2=4");
-        let dirs = dirs.as_slice();
         assert_eq!(dirs.len(), 1);
         assert_eq!(dirs[0].name, Some("crate2".to_string()));
         assert_eq!(dirs[0].level, 4);
@@ -128,7 +126,6 @@ fn parse_logging_spec_invalid_crate() {
     fn parse_logging_spec_invalid_log_level() {
         // test parse_logging_spec with 'noNumber' as log level
         let (dirs, filter) = parse_logging_spec("crate1::mod1=noNumber,crate2=4");
-        let dirs = dirs.as_slice();
         assert_eq!(dirs.len(), 1);
         assert_eq!(dirs[0].name, Some("crate2".to_string()));
         assert_eq!(dirs[0].level, 4);
@@ -139,7 +136,6 @@ fn parse_logging_spec_invalid_log_level() {
     fn parse_logging_spec_string_log_level() {
         // test parse_logging_spec with 'warn' as log level
         let (dirs, filter) = parse_logging_spec("crate1::mod1=wrong,crate2=warn");
-        let dirs = dirs.as_slice();
         assert_eq!(dirs.len(), 1);
         assert_eq!(dirs[0].name, Some("crate2".to_string()));
         assert_eq!(dirs[0].level, ::WARN);
@@ -150,7 +146,6 @@ fn parse_logging_spec_string_log_level() {
     fn parse_logging_spec_empty_log_level() {
         // test parse_logging_spec with '' as log level
         let (dirs, filter) = parse_logging_spec("crate1::mod1=wrong,crate2=");
-        let dirs = dirs.as_slice();
         assert_eq!(dirs.len(), 1);
         assert_eq!(dirs[0].name, Some("crate2".to_string()));
         assert_eq!(dirs[0].level, ::MAX_LOG_LEVEL);
@@ -161,7 +156,6 @@ fn parse_logging_spec_empty_log_level() {
     fn parse_logging_spec_global() {
         // test parse_logging_spec with no crate
         let (dirs, filter) = parse_logging_spec("warn,crate2=4");
-        let dirs = dirs.as_slice();
         assert_eq!(dirs.len(), 2);
         assert_eq!(dirs[0].name, None);
         assert_eq!(dirs[0].level, 2);
@@ -173,7 +167,6 @@ fn parse_logging_spec_global() {
     #[test]
     fn parse_logging_spec_valid_filter() {
         let (dirs, filter) = parse_logging_spec("crate1::mod1=1,crate1::mod2,crate2=4/abc");
-        let dirs = dirs.as_slice();
         assert_eq!(dirs.len(), 3);
         assert_eq!(dirs[0].name, Some("crate1::mod1".to_string()));
         assert_eq!(dirs[0].level, 1);
@@ -183,26 +176,24 @@ fn parse_logging_spec_valid_filter() {
 
         assert_eq!(dirs[2].name, Some("crate2".to_string()));
         assert_eq!(dirs[2].level, 4);
-        assert!(filter.is_some() && filter.unwrap().to_string().as_slice() == "abc");
+        assert!(filter.is_some() && filter.unwrap().to_string() == "abc");
     }
 
     #[test]
     fn parse_logging_spec_invalid_crate_filter() {
         let (dirs, filter) = parse_logging_spec("crate1::mod1=1=2,crate2=4/a.c");
-        let dirs = dirs.as_slice();
         assert_eq!(dirs.len(), 1);
         assert_eq!(dirs[0].name, Some("crate2".to_string()));
         assert_eq!(dirs[0].level, 4);
-        assert!(filter.is_some() && filter.unwrap().to_string().as_slice() == "a.c");
+        assert!(filter.is_some() && filter.unwrap().to_string() == "a.c");
     }
 
     #[test]
     fn parse_logging_spec_empty_with_filter() {
         let (dirs, filter) = parse_logging_spec("crate1/a*c");
-        let dirs = dirs.as_slice();
         assert_eq!(dirs.len(), 1);
         assert_eq!(dirs[0].name, Some("crate1".to_string()));
         assert_eq!(dirs[0].level, ::MAX_LOG_LEVEL);
-        assert!(filter.is_some() && filter.unwrap().to_string().as_slice() == "a*c");
+        assert!(filter.is_some() && filter.unwrap().to_string() == "a*c");
     }
 }
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 2bf3fa992cd669c847c27de3d838ae4e2c93d466..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 {
@@ -523,11 +525,11 @@ fn parse_counted(&mut self) -> Result<(), Error> {
 
         // Parse the min and max values from the regex.
         let (mut min, mut max): (uint, Option<uint>);
-        if !inner.as_slice().contains(",") {
+        if !inner.contains(",") {
             min = try!(self.parse_uint(inner.as_slice()));
             max = Some(min);
         } else {
-            let pieces: Vec<&str> = inner.as_slice().splitn(1, ',').collect();
+            let pieces: Vec<&str> = inner.splitn(1, ',').collect();
             let (smin, smax) = (pieces[0], pieces[1]);
             if smin.len() == 0 {
                 return self.err("Max repetitions cannot be specified \
@@ -751,7 +753,7 @@ fn parse_named_capture(&mut self) -> Result<(), Error> {
             return self.err("Capture names must have at least 1 character.")
         }
         let name = self.slice(self.chari, closer);
-        if !name.as_slice().chars().all(is_valid_cap) {
+        if !name.chars().all(is_valid_cap) {
             return self.err(
                 "Capture names can only have underscores, letters and digits.")
         }
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 2c59950abc3a305c855f92a43506acfb2a007373..27091b6ef4b4dd162ab542ee700ce2a1ce38f2b6 100644 (file)
@@ -156,13 +156,13 @@ fn $name() {
             };
             // The test set sometimes leave out capture groups, so truncate
             // actual capture groups to match test set.
-            let (sexpect, mut sgot) = (expected.as_slice(), got.as_slice());
-            if sgot.len() > sexpect.len() {
-                sgot = sgot[0..sexpect.len()]
+            let mut sgot = got.as_slice();
+            if sgot.len() > expected.len() {
+                sgot = sgot[0..expected.len()]
             }
-            if sexpect != sgot {
+            if expected != sgot {
                 panic!("For RE '{}' against '{}', expected '{}' but got '{}'",
-                      $re, text, sexpect, sgot);
+                      $re, text, expected, sgot);
             }
         }
     );
index 79019d213b8bade51703a6c7aeff8f90d32c2d63..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 {
@@ -147,7 +151,7 @@ fn run(&mut self) -> CaptureLocs {
                 // jump ahead quickly. If it can't be found, then we can bail
                 // out early.
                 if self.prog.prefix.len() > 0 && clist.size == 0 {
-                    let needle = self.prog.prefix.as_slice().as_bytes();
+                    let needle = self.prog.prefix.as_bytes();
                     let haystack = self.input.as_bytes()[self.ic..];
                     match find_prefix(needle, haystack) {
                         None => break,
index 52ec18be97981acbaa61393495ff15af17f01c8f..4df8819774319e782e71a96affd38e3fb26aec4a 100644 (file)
@@ -115,7 +115,7 @@ fn code(&mut self) -> P<ast::Expr> {
         // expression returned.
         let num_cap_locs = 2 * self.prog.num_captures();
         let num_insts = self.prog.insts.len();
-        let cap_names = self.vec_expr(self.names.as_slice().iter(),
+        let cap_names = self.vec_expr(self.names.iter(),
             |cx, name| match *name {
                 Some(ref name) => {
                     let name = name.as_slice();
@@ -125,14 +125,14 @@ fn code(&mut self) -> P<ast::Expr> {
             }
         );
         let prefix_anchor =
-            match self.prog.insts.as_slice()[1] {
+            match self.prog.insts[1] {
                 EmptyBegin(flags) if flags & FLAG_MULTI == 0 => true,
                 _ => false,
             };
         let init_groups = self.vec_expr(range(0, num_cap_locs),
                                         |cx, _| cx.expr_none(self.sp));
 
-        let prefix_lit = Rc::new(self.prog.prefix.as_slice().as_bytes().to_vec());
+        let prefix_lit = Rc::new(self.prog.prefix.as_bytes().to_vec());
         let prefix_bytes = self.cx.expr_lit(self.sp, ast::LitBinary(prefix_lit));
 
         let check_prefix = self.check_prefix();
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 b0ac98c94e748b3f0404369fb027251f461237b6..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 {
@@ -902,7 +924,7 @@ fn to_snake_case(str: &str) -> String {
                 let mut buf = String::new();
                 if s.is_empty() { continue; }
                 for ch in s.chars() {
-                    if !buf.is_empty() && buf.as_slice() != "'"
+                    if !buf.is_empty() && buf != "'"
                                        && ch.is_uppercase()
                                        && !last_upper {
                         words.push(buf);
@@ -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 5a8d60fbecd6c3c71ac369bdeec91e6e74454a15..9e87153e64a1580d71faaf8dcb025a202a37e88f 100644 (file)
@@ -275,9 +275,11 @@ fn visit_item(e: &Env, i: &ast::Item) {
     }
 }
 
-fn register_native_lib(sess: &Session, span: Option<Span>, name: String,
-                       kind: cstore::NativeLibaryKind) {
-    if name.as_slice().is_empty() {
+fn register_native_lib(sess: &Session,
+                       span: Option<Span>,
+                       name: String,
+                       kind: cstore::NativeLibraryKind) {
+    if name.is_empty() {
         match span {
             Some(span) => {
                 sess.span_err(span, "#[link(name = \"\")] given with \
@@ -304,7 +306,7 @@ fn existing_match(e: &Env, name: &str,
                   hash: Option<&Svh>) -> Option<ast::CrateNum> {
     let mut ret = None;
     e.sess.cstore.iter_crate_data(|cnum, data| {
-        if data.name.as_slice() != name { return }
+        if data.name != name { return }
 
         match hash {
             Some(hash) if *hash == data.hash() => { ret = Some(cnum); return }
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 c844c8940fe6247ec17d83a8c349657206a002fa..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>,
 }
@@ -162,7 +166,7 @@ pub fn get_used_crates(&self, prefer: LinkagePreference)
         let mut ordering = Vec::new();
         fn visit(cstore: &CStore, cnum: ast::CrateNum,
                  ordering: &mut Vec<ast::CrateNum>) {
-            if ordering.as_slice().contains(&cnum) { return }
+            if ordering.contains(&cnum) { return }
             let meta = cstore.get_crate_data(cnum);
             for (_, &dep) in meta.cnum_map.iter() {
                 visit(cstore, dep, ordering);
@@ -172,8 +176,7 @@ fn visit(cstore: &CStore, cnum: ast::CrateNum,
         for (&num, _) in self.metas.borrow().iter() {
             visit(self, num, &mut ordering);
         }
-        ordering.as_mut_slice().reverse();
-        let ordering = ordering.as_slice();
+        ordering.reverse();
         let mut libs = self.used_crate_sources.borrow()
             .iter()
             .map(|src| (src.cnum, match prefer {
@@ -187,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
     }
 
@@ -227,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 f7ee9fa65229ce0d0aa4cae02c757185000c926e..a3f56f7f655f5ee31d787254bc5916ab617c95a5 100644 (file)
@@ -474,7 +474,7 @@ fn encode_reexported_static_methods(ecx: &EncodeContext,
         // encoded metadata for static methods relative to Bar,
         // but not yet for Foo.
         //
-        if path_differs || original_name.get() != exp.name.as_slice() {
+        if path_differs || original_name.get() != exp.name {
             if !encode_reexported_static_base_methods(ecx, rbml_w, exp) {
                 if encode_reexported_static_trait_methods(ecx, rbml_w, exp) {
                     debug!("(encode reexported static methods) {} [trait]",
@@ -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 89f3343ef123ac7bf5150057b91e8c7d4617dc2a..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
@@ -214,7 +219,7 @@ pub fn rust_path() -> Vec<Path> {
     let mut env_rust_path: Vec<Path> = match get_rust_path() {
         Some(env_path) => {
             let env_path_components =
-                env_path.as_slice().split_str(PATH_ENTRY_SEPARATOR);
+                env_path.split_str(PATH_ENTRY_SEPARATOR);
             env_path_components.map(|s| Path::new(s)).collect()
         }
         None => Vec::new()
index bd0446dd67ff291fef3c16bfc4ebb0a335b48852..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
 //! |     |
 //! |     |
@@ -545,7 +545,7 @@ fn extract_one(&mut self, m: HashSet<Path>, flavor: &str,
     fn crate_matches(&mut self, crate_data: &[u8], libpath: &Path) -> bool {
         if self.should_match_name {
             match decoder::maybe_get_crate_name(crate_data) {
-                Some(ref name) if self.crate_name == name.as_slice() => {}
+                Some(ref name) if self.crate_name == *name => {}
                 _ => { info!("Rejecting via crate name"); return false }
             }
         }
@@ -560,7 +560,7 @@ fn crate_matches(&mut self, crate_data: &[u8], libpath: &Path) -> bool {
             None => { debug!("triple not present"); return false }
             Some(t) => t,
         };
-        if triple.as_slice() != self.triple {
+        if triple != self.triple {
             info!("Rejecting via crate triple: expected {} got {}", self.triple, triple);
             self.rejected_via_triple.push(CrateMismatch {
                 path: libpath.clone(),
@@ -743,7 +743,7 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo
             let name = String::from_raw_buf_len(name_buf as *const u8,
                                                 name_len as uint);
             debug!("get_metadata_section: name {}", name);
-            if read_meta_section_name(is_osx).as_slice() == name.as_slice() {
+            if read_meta_section_name(is_osx) == name {
                 let cbuf = llvm::LLVMGetSectionContents(si.llsi);
                 let csz = llvm::LLVMGetSectionSize(si.llsi) as uint;
                 let cvbuf: *const u8 = cbuf as *const u8;
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 24273e49c73131579bbdfc62b4225c779ff548e0..5785972c484bbb5a55eedac6b0813db17f6688e3 100644 (file)
@@ -234,15 +234,15 @@ pub fn fixup_fragment_sets<'tcx>(this: &MoveData<'tcx>, tcx: &ty::ctxt<'tcx>) {
     debug!("fragments 3 assigned: {}", path_lps(assigned.as_slice()));
 
     // Fourth, build the leftover from the moved, assigned, and parents.
-    for m in moved.as_slice().iter() {
+    for m in moved.iter() {
         let lp = this.path_loan_path(*m);
         add_fragment_siblings(this, tcx, &mut unmoved, lp, None);
     }
-    for a in assigned.as_slice().iter() {
+    for a in assigned.iter() {
         let lp = this.path_loan_path(*a);
         add_fragment_siblings(this, tcx, &mut unmoved, lp, None);
     }
-    for p in parents.as_slice().iter() {
+    for p in parents.iter() {
         let lp = this.path_loan_path(*p);
         add_fragment_siblings(this, tcx, &mut unmoved, lp, None);
     }
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 92c87aacc7dc5bf75e276fdb9a1b6be4d2f455a1..e33f44967f1ad4661aae2dcc24ad8981baa11344 100644 (file)
@@ -31,14 +31,14 @@ pub struct LabelledCFG<'a, 'ast: 'a> {
 fn replace_newline_with_backslash_l(s: String) -> String {
     // Replacing newlines with \\l causes each line to be left-aligned,
     // improving presentation of (long) pretty-printed expressions.
-    if s.as_slice().contains("\n") {
+    if s.contains("\n") {
         let mut s = s.replace("\n", "\\l");
         // Apparently left-alignment applies to the line that precedes
         // \l, not the line that follows; so, add \l at end of string
         // if not already present, ensuring last line gets left-aligned
         // as well.
         let mut last_two: Vec<_> =
-            s.as_slice().chars().rev().take(2).collect();
+            s.chars().rev().take(2).collect();
         last_two.reverse();
         if last_two != ['\\', 'l'] {
             s.push_str("\\l");
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 03fe87824215925b36e09b4f8338a41f4bc56377..d2f43faa003559c8d5fe32b971db959289a7c4e0 100644 (file)
@@ -321,7 +321,7 @@ fn has_allow_dead_code_or_lang_attr(attrs: &[ast::Attribute]) -> bool {
     for attr in lint::gather_attrs(attrs).into_iter() {
         match attr {
             Ok((ref name, lint::Allow, _))
-                if name.get() == dead_code.as_slice() => return true,
+                if name.get() == dead_code => return true,
             _ => (),
         }
     }
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 523c9f3330968cd875f01ebd58e378e8e4c682c2..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;
@@ -1065,7 +1080,7 @@ fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
                 // the same bindings, and we also consider the first pattern to be
                 // the "authoritative" set of ids
                 let arm_succ =
-                    self.define_bindings_in_arm_pats(arm.pats.as_slice().head().map(|p| &**p),
+                    self.define_bindings_in_arm_pats(arm.pats.head().map(|p| &**p),
                                                      guard_succ);
                 self.merge_from_succ(ln, arm_succ, first_merge);
                 first_merge = false;
@@ -1431,7 +1446,7 @@ fn check_arm(this: &mut Liveness, arm: &ast::Arm) {
     // only consider the first pattern; any later patterns must have
     // the same bindings, and we also consider the first pattern to be
     // the "authoritative" set of ids
-    this.arm_pats_bindings(arm.pats.as_slice().head().map(|p| &**p), |this, ln, var, sp, id| {
+    this.arm_pats_bindings(arm.pats.head().map(|p| &**p), |this, ln, var, sp, id| {
         this.warn_about_unused(sp, id, ln, var);
     });
     visit::walk_arm(this, arm);
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 f1a75f996b09240158f41bb6582e4bf8ea48af0a..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 {
@@ -1668,7 +1708,7 @@ fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
                 let module_path = match view_path.node {
                     ViewPathSimple(_, ref full_path, _) => {
                         full_path.segments
-                            .as_slice().init()
+                            .init()
                             .iter().map(|ident| ident.identifier.name)
                             .collect()
                     }
@@ -1739,7 +1779,7 @@ fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
                                             continue;
                                         }
                                     };
-                                    let module_path = module_path.as_slice().init();
+                                    let module_path = module_path.init();
                                     (module_path.to_vec(), name)
                                 }
                             };
@@ -3760,12 +3800,12 @@ fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
                          .codemap()
                          .span_to_snippet((*imports)[index].span)
                          .unwrap();
-            if sn.as_slice().contains("::") {
+            if sn.contains("::") {
                 self.resolve_error((*imports)[index].span,
                                    "unresolved import");
             } else {
                 let err = format!("unresolved import (maybe you meant `{}::*`?)",
-                                  sn.as_slice().slice(0, sn.len()));
+                                  sn.slice(0, sn.len()));
                 self.resolve_error((*imports)[index].span, err.as_slice());
             }
         }
@@ -5773,7 +5813,7 @@ fn resolve_expr(&mut self, expr: &Expr) {
                                 });
 
                                 if method_scope && token::get_name(self.self_name).get()
-                                                                   == wrong_name.as_slice() {
+                                                                   == wrong_name {
                                         self.resolve_error(
                                             expr.span,
                                             "`self` is not available \
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 994f0c2090a57245964898f223f1d740c4df1b78..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)
     }
@@ -2907,7 +2977,7 @@ fn tc_ty<'tcx>(cx: &ctxt<'tcx>,
                         res = res | TC::ReachesFfiUnsafe;
                     }
 
-                    match repr_hints.as_slice().get(0) {
+                    match repr_hints.get(0) {
                         Some(h) => if !h.is_ffi_safe() {
                             res = res | TC::ReachesFfiUnsafe;
                         },
@@ -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>)
@@ -3566,23 +3655,23 @@ pub fn positional_element_ty<'tcx>(cx: &ctxt<'tcx>,
                                    variant: Option<ast::DefId>) -> Option<Ty<'tcx>> {
 
     match (&ty.sty, variant) {
-        (&ty_tup(ref v), None) => v.as_slice().get(i).map(|&t| t),
+        (&ty_tup(ref v), None) => v.get(i).map(|&t| t),
 
 
         (&ty_struct(def_id, ref substs), None) => lookup_struct_fields(cx, def_id)
-            .as_slice().get(i)
+            .get(i)
             .map(|&t|lookup_item_type(cx, t.id).ty.subst(cx, substs)),
 
         (&ty_enum(def_id, ref substs), Some(variant_def_id)) => {
             let variant_info = enum_variant_with_id(cx, def_id, variant_def_id);
-            variant_info.args.as_slice().get(i).map(|t|t.subst(cx, substs))
+            variant_info.args.get(i).map(|t|t.subst(cx, substs))
         }
 
         (&ty_enum(def_id, ref substs), None) => {
             assert!(enum_is_univariant(cx, def_id));
             let enum_variants = enum_variants(cx, def_id);
             let variant_info = &(*enum_variants)[0];
-            variant_info.args.as_slice().get(i).map(|t|t.subst(cx, substs))
+            variant_info.args.get(i).map(|t|t.subst(cx, substs))
         }
 
         _ => None
@@ -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 cbc9dd9145bfb7fd4382d676ce37f4e30b10bd51..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;
@@ -512,13 +522,13 @@ pub fn build_codegen_options(matches: &getopts::Matches) -> CodegenOptions
 {
     let mut cg = basic_codegen_options();
     for option in matches.opt_strs("C").into_iter() {
-        let mut iter = option.as_slice().splitn(1, '=');
+        let mut iter = option.splitn(1, '=');
         let key = iter.next().unwrap();
         let value = iter.next();
         let option_to_lookup = key.replace("-", "_");
         let mut found = false;
         for &(candidate, setter, opt_type_desc, _) in CG_OPTIONS.iter() {
-            if option_to_lookup.as_slice() != candidate { continue }
+            if option_to_lookup != candidate { continue }
             if !setter(&mut cg, value) {
                 match (value, opt_type_desc) {
                     (Some(..), None) => {
@@ -714,7 +724,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
 
     for &level in [lint::Allow, lint::Warn, lint::Deny, lint::Forbid].iter() {
         for lint_name in matches.opt_strs(level.as_str()).into_iter() {
-            if lint_name.as_slice() == "help" {
+            if lint_name == "help" {
                 describe_lints = true;
             } else {
                 lint_opts.push((lint_name.replace("-", "_").into_string(), level));
@@ -727,9 +737,8 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
     let debug_map = debugging_opts_map();
     for debug_flag in debug_flags.iter() {
         let mut this_bit = 0;
-        for tuple in debug_map.iter() {
-            let (name, bit) = match *tuple { (ref a, _, b) => (a, b) };
-            if *name == debug_flag.as_slice() {
+        for &(name, _, bit) in debug_map.iter() {
+            if name == *debug_flag {
                 this_bit = bit;
                 break;
             }
@@ -749,7 +758,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
     if !parse_only && !no_trans {
         let unparsed_output_types = matches.opt_strs("emit");
         for unparsed_output_type in unparsed_output_types.iter() {
-            for part in unparsed_output_type.as_slice().split(',') {
+            for part in unparsed_output_type.split(',') {
                 let output_type = match part.as_slice() {
                     "asm"  => OutputTypeAssembly,
                     "ir"   => OutputTypeLlvmAssembly,
@@ -765,7 +774,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
             }
         }
     };
-    output_types.as_mut_slice().sort();
+    output_types.sort();
     output_types.dedup();
     if output_types.len() == 0 {
         output_types.push(OutputTypeExe);
@@ -824,7 +833,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
     }).collect();
 
     let libs = matches.opt_strs("l").into_iter().map(|s| {
-        let mut parts = s.as_slice().rsplitn(1, ':');
+        let mut parts = s.rsplitn(1, ':');
         let kind = parts.next().unwrap();
         let (name, kind) = match (parts.next(), kind) {
             (None, name) |
@@ -875,7 +884,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
 
     let mut externs = HashMap::new();
     for arg in matches.opt_strs("extern").iter() {
-        let mut parts = arg.as_slice().splitn(1, '=');
+        let mut parts = arg.splitn(1, '=');
         let name = match parts.next() {
             Some(s) => s,
             None => early_error("--extern value must not be empty"),
@@ -925,7 +934,7 @@ pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateTy
 
     let mut crate_types: Vec<CrateType> = Vec::new();
     for unparsed_crate_type in list_list.iter() {
-        for part in unparsed_crate_type.as_slice().split(',') {
+        for part in unparsed_crate_type.split(',') {
             let new_part = match part {
                 "lib"       => default_lib_output(),
                 "rlib"      => CrateTypeRlib,
index 047e5985569ae41f0f2f4cb0f56194151da5112c..e4d34e09d330a5cc64bc00e8c6ad4576fdbdcc63 100644 (file)
@@ -257,7 +257,7 @@ pub fn build_session_(sopts: config::Options,
 
     let can_print_warnings = sopts.lint_opts
         .iter()
-        .filter(|&&(ref key, _)| key.as_slice() == "warnings")
+        .filter(|&&(ref key, _)| *key == "warnings")
         .map(|&(_, ref level)| *level != lint::Allow)
         .last()
         .unwrap_or(true);
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 1283e89c29d0cdf79b02e1724ff50d2426330deb..3895a1137267433b93468922e8aa041c5d2ee43d 100644 (file)
@@ -538,7 +538,7 @@ pub fn parameterized<'tcx>(cx: &ctxt<'tcx>,
 pub fn ty_to_short_str<'tcx>(cx: &ctxt<'tcx>, typ: Ty<'tcx>) -> String {
     let mut s = typ.repr(cx).to_string();
     if s.len() >= 32u {
-        s = s.as_slice().slice(0u, 32u).to_string();
+        s = s.slice(0u, 32u).to_string();
     }
     return s;
 }
index 134f7105ea76eddfc0726814eeaac726d66061a5..ea4d5c820f8b8796afb5faca1cdc134553a3d350 100644 (file)
@@ -12,7 +12,7 @@
 use syntax::abi;
 
 pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
-    let cc_args = if target_triple.as_slice().contains("thumb") {
+    let cc_args = if target_triple.contains("thumb") {
         vec!("-mthumb".to_string())
     } else {
         vec!("-marm".to_string())
index 9c94823f867586d6c1296d08d31b923574fc1a2f..a90b49ba101fa57c426ed54a63ce92aa2686edc7 100644 (file)
@@ -145,8 +145,8 @@ fn test_rpaths_to_flags() {
             "path2".to_string()
         ]);
         assert_eq!(flags,
-                   vec!("-Wl,-rpath,path1".to_string(),
-                        "-Wl,-rpath,path2".to_string()));
+                   ["-Wl,-rpath,path1",
+                    "-Wl,-rpath,path2"]);
     }
 
     #[test]
@@ -156,9 +156,9 @@ fn test_minimize1() {
             "rpath2".to_string(),
             "rpath1".to_string()
         ]);
-        assert!(res.as_slice() == [
-            "rpath1".to_string(),
-            "rpath2".to_string()
+        assert!(res == [
+            "rpath1",
+            "rpath2",
         ]);
     }
 
@@ -176,11 +176,11 @@ fn test_minimize2() {
             "4a".to_string(),
             "3".to_string()
         ]);
-        assert!(res.as_slice() == [
-            "1a".to_string(),
-            "2".to_string(),
-            "4a".to_string(),
-            "3".to_string()
+        assert!(res == [
+            "1a",
+            "2",
+            "4a",
+            "3",
         ]);
     }
 
@@ -196,7 +196,7 @@ fn test_rpath_relative() {
             realpath: |p| Ok(p.clone())
         };
         let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
-        assert_eq!(res.as_slice(), "$ORIGIN/../lib");
+        assert_eq!(res, "$ORIGIN/../lib");
     }
 
     #[test]
@@ -211,7 +211,7 @@ fn test_rpath_relative() {
             realpath: |p| Ok(p.clone())
         };
         let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
-        assert_eq!(res.as_slice(), "$ORIGIN/../lib");
+        assert_eq!(res, "$ORIGIN/../lib");
     }
 
     #[test]
@@ -226,7 +226,7 @@ fn test_rpath_relative() {
             realpath: |p| Ok(p.clone())
         };
         let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
-        assert_eq!(res.as_slice(), "$ORIGIN/../lib");
+        assert_eq!(res, "$ORIGIN/../lib");
     }
 
     #[test]
@@ -241,6 +241,6 @@ fn test_rpath_relative() {
             realpath: |p| Ok(p.clone())
         };
         let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
-        assert_eq!(res.as_slice(), "@loader_path/../lib");
+        assert_eq!(res, "@loader_path/../lib");
     }
 }
index 4c08c82ecac5a42cb4ff2d07308bbbbc0996b0a8..1b662ef17876007c53c34385c25ca138f93ca417 100644 (file)
@@ -263,7 +263,7 @@ fn result_bytes(&mut self) -> Vec<u8> {
     /// Convenience function that retrieves the result of a digest as a
     /// String in hexadecimal format.
     fn result_str(&mut self) -> String {
-        self.result_bytes().as_slice().to_hex().to_string()
+        self.result_bytes().to_hex().to_string()
     }
 }
 
@@ -568,7 +568,6 @@ fn test_hash<D: Digest>(sh: &mut D, tests: &[Test]) {
             while left > 0u {
                 let take = (left + 1u) / 2u;
                 sh.input_str(t.input
-                              .as_slice()
                               .slice(len - left, take + len - left));
                 left = left - take;
             }
index 68a80edc5d07f14aa24788df7b385aec7f65150b..76adc4e472f82b7e98f0387d0d8744086a217813 100644 (file)
@@ -200,7 +200,7 @@ impl Target {
     pub fn adjust_abi(&self, abi: abi::Abi) -> abi::Abi {
         match abi {
             abi::System => {
-                if self.options.is_like_windows && self.arch.as_slice() == "x86" {
+                if self.options.is_like_windows && self.arch == "x86" {
                     abi::Stdcall
                 } else {
                     abi::C
@@ -308,7 +308,6 @@ macro_rules! load_specific (
             ( $($name:ident),+ ) => (
                 {
                     let target = target.replace("-", "_");
-                    let target = target.as_slice();
                     if false { }
                     $(
                         else if target == stringify!($name) {
index 437b0257a9759f18e3500ec0a79f23ba7a639d23..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
     //
@@ -682,7 +686,7 @@ pub fn collect_crate_types(session: &Session,
         if base.len() == 0 {
             base.push(link::default_output_for_target(session));
         }
-        base.as_mut_slice().sort();
+        base.sort();
         base.dedup();
     }
 
index 33c009cf3291bcb61f870aabc61c165e3740c1a5..7f15f5e87d9dd3372db2171b21972cbb4ad4ac61 100644 (file)
@@ -378,13 +378,13 @@ pub fn handle_options(mut args: Vec<String>) -> Option<getopts::Matches> {
     // Don't handle -W help here, because we might first load plugins.
 
     let r = matches.opt_strs("Z");
-    if r.iter().any(|x| x.as_slice() == "help") {
+    if r.iter().any(|x| *x == "help") {
         describe_debug_flags();
         return None;
     }
 
     let cg_flags = matches.opt_strs("C");
-    if cg_flags.iter().any(|x| x.as_slice() == "help") {
+    if cg_flags.iter().any(|x| *x == "help") {
         describe_codegen_flags();
         return None;
     }
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 6057f9d90819029e473e745c9681ba7882e27d7e..62f8177ed758d36dd313ee49d08a73d7187b9988 100644 (file)
@@ -140,7 +140,7 @@ pub fn find_crate_name(sess: Option<&Session>,
     if let Some(sess) = sess {
         if let Some(ref s) = sess.opts.crate_name {
             if let Some((attr, ref name)) = attr_crate_name {
-                if s.as_slice() != name.get() {
+                if *s != name.get() {
                     let msg = format!("--crate-name and #[crate_name] are \
                                        required to match, but `{}` != `{}`",
                                       s, name);
@@ -249,7 +249,7 @@ pub fn sanitize(s: &str) -> String {
                 let mut tstr = String::new();
                 for c in c.escape_unicode() { tstr.push(c) }
                 result.push('$');
-                result.push_str(tstr.as_slice().slice_from(1));
+                result.push_str(tstr.slice_from(1));
             }
         }
     }
@@ -669,7 +669,7 @@ fn link_rlib<'a>(sess: &'a Session,
 fn write_rlib_bytecode_object_v1<T: Writer>(writer: &mut T,
                                             bc_data_deflated: &[u8])
                                          -> ::std::io::IoResult<()> {
-    let bc_data_deflated_size: u64 = bc_data_deflated.as_slice().len() as u64;
+    let bc_data_deflated_size: u64 = bc_data_deflated.len() as u64;
 
     try! { writer.write(RLIB_BYTECODE_OBJECT_MAGIC) };
     try! { writer.write_le_u32(1) };
@@ -910,10 +910,10 @@ fn link_args(cmd: &mut Command,
         let args = sess.opts.cg.link_args.as_ref().unwrap_or(&empty_vec);
         let mut args = args.iter().chain(used_link_args.iter());
         if !dylib
-            && (t.options.relocation_model.as_slice() == "pic"
-                || sess.opts.cg.relocation_model.as_ref()
-                   .unwrap_or(&empty_str).as_slice() == "pic")
-            && !args.any(|x| x.as_slice() == "-static") {
+            && (t.options.relocation_model == "pic"
+                || *sess.opts.cg.relocation_model.as_ref()
+                   .unwrap_or(&empty_str) == "pic")
+            && !args.any(|x| *x == "-static") {
             cmd.arg("-pie");
         }
     }
index 407f632bee7ddf610c3a3ddef1fb0e5ee5bf1c53..a715849ddf62f607fcd17b26230889a58bbcbeb6 100644 (file)
@@ -143,7 +143,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
 
     // Internalize everything but the reachable symbols of the current module
     let cstrs: Vec<::std::c_str::CString> =
-        reachable.iter().map(|s| s.as_slice().to_c_str()).collect();
+        reachable.iter().map(|s| s.to_c_str()).collect();
     let arr: Vec<*const i8> = cstrs.iter().map(|c| c.as_ptr()).collect();
     let ptr = arr.as_ptr();
     unsafe {
index e5ffe2675d6f4fdcf6d192a1942f6c3b6177751f..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();
@@ -363,7 +374,7 @@ struct HandlerFreeVars<'a> {
             let pass_name = pass_name.as_str().expect("got a non-UTF8 pass name from LLVM");
             let enabled = match cgcx.remark {
                 AllPasses => true,
-                SomePasses(ref v) => v.iter().any(|s| s.as_slice() == pass_name),
+                SomePasses(ref v) => v.iter().any(|s| *s == pass_name),
             };
 
             if enabled {
@@ -421,7 +432,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
             // If we're verifying or linting, add them to the function pass
             // manager.
             let addpass = |pass: &str| {
-                pass.as_slice().with_c_str(|s| llvm::LLVMRustAddPass(fpm, s))
+                pass.with_c_str(|s| llvm::LLVMRustAddPass(fpm, s))
             };
             if !config.no_verify { assert!(addpass("verify")); }
 
@@ -433,7 +444,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
             }
 
             for pass in config.passes.iter() {
-                pass.as_slice().with_c_str(|s| {
+                pass.with_c_str(|s| {
                     if !llvm::LLVMRustAddPass(mpm, s) {
                         cgcx.handler.warn(format!("unknown pass {}, ignoring",
                                                   *pass).as_slice());
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 2102133f97d3d52c3e7dd14e1aff19860945198f..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 {
@@ -163,7 +165,7 @@ pub fn make_values_str(&self,
         let values = values.iter().map(|s| {
             // Never take more than 1020 chars
             if s.len() > 1020 {
-                s.as_slice().slice_to(1020)
+                s.slice_to(1020)
             } else {
                 s.as_slice()
             }
@@ -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 77102d2db39bb751e00fc5ad74ceadac1cdd0ea2..e3afe22897e39bb862585dc886af93e7bbc1a551 100644 (file)
@@ -122,7 +122,7 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
     };
 
     let r = ia.asm.get().with_c_str(|a| {
-        constraints.as_slice().with_c_str(|c| {
+        constraints.with_c_str(|c| {
             InlineAsmCall(bcx,
                           a,
                           c,
index 9d0e096c71d646758191a6798557ca7c07cac1ab..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
@@ -2739,7 +2755,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
                                 format!("Illegal null byte in export_name \
                                          value: `{}`", sym).as_slice());
                         }
-                        let g = sym.as_slice().with_c_str(|buf| {
+                        let g = sym.with_c_str(|buf| {
                             llvm::LLVMAddGlobal(ccx.llmod(), llty, buf)
                         });
 
@@ -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 526592181ae646824231a4670848b7f1f22e8006..cf940b1384671aed060127ff63ebf057b1e5e443 100644 (file)
@@ -774,7 +774,7 @@ pub fn add_comment(&self, text: &str) {
             let comment_text = format!("{} {}", "#",
                                        sanitized.replace("\n", "\n\t# "));
             self.count_insn("inlineasm");
-            let asm = comment_text.as_slice().with_c_str(|c| {
+            let asm = comment_text.with_c_str(|c| {
                 unsafe {
                     llvm::LLVMConstInlineAsm(Type::func(&[], &Type::void(self.ccx)).to_ref(),
                                              c, noname(), False, False)
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 fd9d6b8f2c3b20b6ee1e6e6e14c2ac6eca5f9926..3b5197594a128d3924e84adca809a19e60a1398a 100644 (file)
@@ -222,14 +222,12 @@ unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextR
     sess.target
         .target
         .data_layout
-        .as_slice()
         .with_c_str(|buf| {
         llvm::LLVMSetDataLayout(llmod, buf);
     });
     sess.target
         .target
         .llvm_target
-        .as_slice()
         .with_c_str(|buf| {
         llvm::LLVMRustSetNormalizedTarget(llmod, buf);
     });
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 555cb0004892fd08af9d3f8edc3057ea91222ff4..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
@@ -824,8 +826,8 @@ pub fn create_global_var_metadata(cx: &CrateContext,
         namespace_node.mangled_name_of_contained_item(var_name.as_slice());
     let var_scope = namespace_node.scope;
 
-    var_name.as_slice().with_c_str(|var_name| {
-        linkage_name.as_slice().with_c_str(|linkage_name| {
+    var_name.with_c_str(|var_name| {
+        linkage_name.with_c_str(|linkage_name| {
             unsafe {
                 llvm::LLVMDIBuilderCreateStaticVariable(DIB(cx),
                                                         var_scope,
@@ -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);
@@ -1323,7 +1327,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         let containing_scope = namespace_node.scope;
         (linkage_name, containing_scope)
     } else {
-        (function_name.as_slice().to_string(), file_metadata)
+        (function_name.clone(), file_metadata)
     };
 
     // Clang sets this parameter to the opening brace of the function's block,
@@ -1332,8 +1336,8 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     let is_local_to_unit = is_node_local_to_unit(cx, fn_ast_id);
 
-    let fn_metadata = function_name.as_slice().with_c_str(|function_name| {
-                          linkage_name.as_slice().with_c_str(|linkage_name| {
+    let fn_metadata = function_name.with_c_str(|function_name| {
+                          linkage_name.with_c_str(|linkage_name| {
             unsafe {
                 llvm::LLVMDIBuilderCreateFunction(
                     DIB(cx),
@@ -1554,7 +1558,7 @@ fn compile_unit_metadata(cx: &CrateContext) {
                                 path_bytes.insert(1, prefix[1]);
                             }
 
-                            path_bytes.as_slice().to_c_str()
+                            path_bytes.to_c_str()
                         }
                     _ => fallback_path(cx)
                 }
@@ -1589,7 +1593,7 @@ fn compile_unit_metadata(cx: &CrateContext) {
     });
 
     fn fallback_path(cx: &CrateContext) -> CString {
-        cx.link_meta().crate_name.as_slice().to_c_str()
+        cx.link_meta().crate_name.to_c_str()
     }
 }
 
@@ -1796,7 +1800,7 @@ fn pointer_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let pointer_llvm_type = type_of::type_of(cx, pointer_type);
     let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type);
     let name = compute_debuginfo_type_name(cx, pointer_type, false);
-    let ptr_metadata = name.as_slice().with_c_str(|name| {
+    let ptr_metadata = name.with_c_str(|name| {
         unsafe {
             llvm::LLVMDIBuilderCreatePointerType(
                 DIB(cx),
@@ -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
@@ -2488,8 +2494,8 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                              .borrow()
                              .get_unique_type_id_as_string(unique_type_id);
 
-    let enum_metadata = enum_name.as_slice().with_c_str(|enum_name| {
-        unique_type_id_str.as_slice().with_c_str(|unique_type_id_str| {
+    let enum_metadata = enum_name.with_c_str(|enum_name| {
+        unique_type_id_str.with_c_str(|unique_type_id_str| {
             unsafe {
                 llvm::LLVMDIBuilderCreateUnionType(
                 DIB(cx),
@@ -2616,7 +2622,7 @@ fn set_members_of_composite_type(cx: &CrateContext,
                 ComputedMemberOffset => machine::llelement_offset(cx, composite_llvm_type, i)
             };
 
-            member_description.name.as_slice().with_c_str(|member_name| {
+            member_description.name.with_c_str(|member_name| {
                 unsafe {
                     llvm::LLVMDIBuilderCreateMemberType(
                         DIB(cx),
@@ -2656,7 +2662,7 @@ fn create_struct_stub(cx: &CrateContext,
                                               .get_unique_type_id_as_string(unique_type_id);
     let metadata_stub = unsafe {
         struct_type_name.with_c_str(|name| {
-            unique_type_id_str.as_slice().with_c_str(|unique_type_id| {
+            unique_type_id_str.with_c_str(|unique_type_id| {
                 // LLVMDIBuilderCreateStructType() wants an empty array. A null
                 // pointer will lead to hard to trace and debug LLVM assertions
                 // later on in llvm/lib/IR/Value.cpp.
@@ -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 fbaf1e6581060ccb5f360462679b598663d879a6..4575d8a41e52a389aea96e8c127dea99ca84bb43 100644 (file)
@@ -496,7 +496,7 @@ pub fn declare_tydesc<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>)
     let llalign = llalign_of(ccx, llty);
     let name = mangle_internal_name_by_type_and_seq(ccx, t, "tydesc");
     debug!("+++ declare_tydesc {} {}", ppaux::ty_to_string(ccx.tcx(), t), name);
-    let gvar = name.as_slice().with_c_str(|buf| {
+    let gvar = name.with_c_str(|buf| {
         unsafe {
             llvm::LLVMAddGlobal(ccx.llmod(), ccx.tydesc_type().to_ref(), buf)
         }
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 1f30dc9040d527cc1f3c817962345cf9c610c3e9..3ee07df6ed447d38336a711143678a98f7768382 100644 (file)
@@ -341,10 +341,10 @@ fn build_impl(cx: &DocContext, tcx: &ty::ctxt,
 
     fn is_doc_hidden(a: &clean::Attribute) -> bool {
         match *a {
-            clean::List(ref name, ref inner) if name.as_slice() == "doc" => {
+            clean::List(ref name, ref inner) if *name == "doc" => {
                 inner.iter().any(|a| {
                     match *a {
-                        clean::Word(ref s) => s.as_slice() == "hidden",
+                        clean::Word(ref s) => *s == "hidden",
                         _ => false,
                     }
                 })
index 7e02891160ad2fa96f63b2c386053442c843ee73..df7b922bd1abc31a4884633a13d4e6c433affb4a 100644 (file)
@@ -256,7 +256,7 @@ impl Item {
     pub fn doc_list<'a>(&'a self) -> Option<&'a [Attribute]> {
         for attr in self.attrs.iter() {
             match *attr {
-                List(ref x, ref list) if "doc" == x.as_slice() => {
+                List(ref x, ref list) if "doc" == *x => {
                     return Some(list.as_slice());
                 }
                 _ => {}
@@ -270,7 +270,7 @@ pub fn doc_list<'a>(&'a self) -> Option<&'a [Attribute]> {
     pub fn doc_value<'a>(&'a self) -> Option<&'a str> {
         for attr in self.attrs.iter() {
             match *attr {
-                NameValue(ref x, ref v) if "doc" == x.as_slice() => {
+                NameValue(ref x, ref v) if "doc" == *x => {
                     return Some(v.as_slice());
                 }
                 _ => {}
@@ -284,7 +284,7 @@ pub fn is_hidden_from_doc(&self) -> bool {
             Some(ref l) => {
                 for innerattr in l.iter() {
                     match *innerattr {
-                        Word(ref s) if "hidden" == s.as_slice() => {
+                        Word(ref s) if "hidden" == *s => {
                             return true
                         }
                         _ => (),
@@ -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() {
@@ -1217,13 +1221,13 @@ fn from_str(s: &str) -> Option<PrimitiveType> {
     fn find(attrs: &[Attribute]) -> Option<PrimitiveType> {
         for attr in attrs.iter() {
             let list = match *attr {
-                List(ref k, ref l) if k.as_slice() == "doc" => l,
+                List(ref k, ref l) if *k == "doc" => l,
                 _ => continue,
             };
             for sub_attr in list.iter() {
                 let value = match *sub_attr {
                     NameValue(ref k, ref v)
-                        if k.as_slice() == "primitive" => v.as_slice(),
+                        if *k == "primitive" => v.as_slice(),
                     _ => continue,
                 };
                 match PrimitiveType::from_str(value) {
@@ -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 9861d18ce51f0b245f52f5785487c47a0280db36..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
@@ -251,8 +256,8 @@ fn path(w: &mut fmt::Formatter, path: &clean::Path, print_all: bool,
             Some(root) => {
                 let mut root = String::from_str(root.as_slice());
                 for seg in path.segments[..amt].iter() {
-                    if "super" == seg.name.as_slice() ||
-                            "self" == seg.name.as_slice() {
+                    if "super" == seg.name ||
+                            "self" == seg.name {
                         try!(write!(w, "{}::", seg.name));
                     } else {
                         root.push_str(seg.name.as_slice());
@@ -337,7 +342,7 @@ fn primitive_link(f: &mut fmt::Formatter,
                 Some(root) => {
                     try!(write!(f, "<a href='{}{}/primitive.{}.html'>",
                                 root,
-                                path.ref0().as_slice().head().unwrap(),
+                                path.ref0().head().unwrap(),
                                 prim.to_url_str()));
                     needs_termination = true;
                 }
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 df25daa3ca1acba0829a537ed7e318f50074b835..10563c61e1465d93bd095ecaa93c97e7850a6b3c 100644 (file)
@@ -231,7 +231,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
         };
 
         // Transform the contents of the header into a hyphenated string
-        let id = s.as_slice().words().map(|s| s.to_ascii_lower())
+        let id = s.words().map(|s| s.to_ascii_lower())
             .collect::<Vec<String>>().connect("-");
 
         // This is a terrible hack working around how hoedown gives us rendered
@@ -393,7 +393,7 @@ fn parse(string: &str) -> LangString {
         let mut seen_other_tags = false;
         let mut data = LangString::all_false();
 
-        let mut tokens = string.as_slice().split(|c: char|
+        let mut tokens = string.split(|c: char|
             !(c == '_' || c == '-' || c.is_alphanumeric())
         );
 
index 9eee8e04f0c2bf505d61406d2eaede7f1a3e0ea0..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
@@ -277,15 +283,15 @@ pub fn run(mut krate: clean::Crate,
             for attr in attrs.iter() {
                 match *attr {
                     clean::NameValue(ref x, ref s)
-                            if "html_favicon_url" == x.as_slice() => {
+                            if "html_favicon_url" == *x => {
                         cx.layout.favicon = s.to_string();
                     }
                     clean::NameValue(ref x, ref s)
-                            if "html_logo_url" == x.as_slice() => {
+                            if "html_logo_url" == *x => {
                         cx.layout.logo = s.to_string();
                     }
                     clean::NameValue(ref x, ref s)
-                            if "html_playground_url" == x.as_slice() => {
+                            if "html_playground_url" == *x => {
                         cx.layout.playground_url = s.to_string();
                         markdown::PLAYGROUND_KRATE.with(|slot| {
                             if slot.borrow().is_none() {
@@ -295,7 +301,7 @@ pub fn run(mut krate: clean::Crate,
                         });
                     }
                     clean::Word(ref x)
-                            if "html_no_source" == x.as_slice() => {
+                            if "html_no_source" == *x => {
                         cx.include_sources = false;
                     }
                     _ => {}
@@ -434,7 +440,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::IoResult<String>
     for (i, item) in cache.search_index.iter().enumerate() {
         // Omit the path if it is same to that of the prior item.
         let path;
-        if lastpath.as_slice() == item.path.as_slice() {
+        if lastpath == item.path {
             path = "";
         } else {
             lastpath = item.path.to_string();
@@ -513,10 +519,10 @@ fn collect(path: &Path, krate: &str,
         if path.exists() {
             for line in BufferedReader::new(File::open(path)).lines() {
                 let line = try!(line);
-                if !line.as_slice().starts_with(key) {
+                if !line.starts_with(key) {
                     continue
                 }
-                if line.as_slice().starts_with(
+                if line.starts_with(
                         format!("{}['{}']", key, krate).as_slice()) {
                     continue
                 }
@@ -670,12 +676,12 @@ fn extern_location(e: &clean::ExternalCrate, dst: &Path) -> ExternalLocation {
     // external crate
     for attr in e.attrs.iter() {
         match *attr {
-            clean::List(ref x, ref list) if "doc" == x.as_slice() => {
+            clean::List(ref x, ref list) if "doc" == *x => {
                 for attr in list.iter() {
                     match *attr {
                         clean::NameValue(ref x, ref s)
-                                if "html_root_url" == x.as_slice() => {
-                            if s.as_slice().ends_with("/") {
+                                if "html_root_url" == *x => {
+                            if s.ends_with("/") {
                                 return Remote(s.to_string());
                             }
                             return Remote(format!("{}/", s));
@@ -964,7 +970,7 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
                         let dox = match attrs.into_iter().find(|a| {
                             match *a {
                                 clean::NameValue(ref x, _)
-                                        if "doc" == x.as_slice() => {
+                                        if "doc" == *x => {
                                     true
                                 }
                                 _ => false
@@ -1261,7 +1267,7 @@ fn build_sidebar(&self, m: &clean::Module) -> HashMap<String, Vec<String>> {
         }
 
         for (_, items) in map.iter_mut() {
-            items.as_mut_slice().sort();
+            items.sort();
         }
         return map;
     }
index 66108bea9885c7ff8004c0ffcb433725f3d155d2..6d9e8dc722f8a6b09850a7fdd3d7370a077f80b5 100644 (file)
@@ -299,7 +299,7 @@ fn acquire_input(input: &str,
 fn parse_externs(matches: &getopts::Matches) -> Result<core::Externs, String> {
     let mut externs = HashMap::new();
     for arg in matches.opt_strs("extern").iter() {
-        let mut parts = arg.as_slice().splitn(1, '=');
+        let mut parts = arg.splitn(1, '=');
         let name = match parts.next() {
             Some(s) => s,
             None => {
@@ -363,18 +363,18 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche
             for inner in nested.iter() {
                 match *inner {
                     clean::Word(ref x)
-                            if "no_default_passes" == x.as_slice() => {
+                            if "no_default_passes" == *x => {
                         default_passes = false;
                     }
                     clean::NameValue(ref x, ref value)
-                            if "passes" == x.as_slice() => {
-                        for pass in value.as_slice().words() {
+                            if "passes" == *x => {
+                        for pass in value.words() {
                             passes.push(pass.to_string());
                         }
                     }
                     clean::NameValue(ref x, ref value)
-                            if "plugins" == x.as_slice() => {
-                        for p in value.as_slice().words() {
+                            if "plugins" == *x => {
+                        for p in value.words() {
                             plugins.push(p.to_string());
                         }
                     }
@@ -397,7 +397,7 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche
     for pass in passes.iter() {
         let plugin = match PASSES.iter()
                                  .position(|&(p, _, _)| {
-                                     p == pass.as_slice()
+                                     p == *pass
                                  }) {
             Some(i) => PASSES[i].val1(),
             None => {
@@ -434,7 +434,7 @@ fn json_input(input: &str) -> Result<Output, String> {
             // Make sure the schema is what we expect
             match obj.remove(&"schema".to_string()) {
                 Some(Json::String(version)) => {
-                    if version.as_slice() != SCHEMA_VERSION {
+                    if version != SCHEMA_VERSION {
                         return Err(format!(
                                 "sorry, but I only understand version {}",
                                 SCHEMA_VERSION))
index 8675d2b3749cd33ef1396b18906af3b145612d9b..e368d7f93320c74c3c01ce03f32881b7b458abfd 100644 (file)
@@ -258,7 +258,7 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
             for attr in i.attrs.iter() {
                 match attr {
                     &clean::NameValue(ref x, ref s)
-                            if "doc" == x.as_slice() => {
+                            if "doc" == *x => {
                         avec.push(clean::NameValue("doc".to_string(),
                                                    unindent(s.as_slice())))
                     }
@@ -283,7 +283,7 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
             for attr in i.attrs.iter() {
                 match *attr {
                     clean::NameValue(ref x, ref s)
-                            if "doc" == x.as_slice() => {
+                            if "doc" == *x => {
                         docstr.push_str(s.as_slice());
                         docstr.push('\n');
                     },
@@ -291,7 +291,7 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
                 }
             }
             let mut a: Vec<clean::Attribute> = i.attrs.iter().filter(|&a| match a {
-                &clean::NameValue(ref x, _) if "doc" == x.as_slice() => false,
+                &clean::NameValue(ref x, _) if "doc" == *x => false,
                 _ => true
             }).map(|x| x.clone()).collect();
             if docstr.len() > 0 {
@@ -374,14 +374,14 @@ mod unindent_tests {
     fn should_unindent() {
         let s = "    line1\n    line2".to_string();
         let r = unindent(s.as_slice());
-        assert_eq!(r.as_slice(), "line1\nline2");
+        assert_eq!(r, "line1\nline2");
     }
 
     #[test]
     fn should_unindent_multiple_paragraphs() {
         let s = "    line1\n\n    line2".to_string();
         let r = unindent(s.as_slice());
-        assert_eq!(r.as_slice(), "line1\n\nline2");
+        assert_eq!(r, "line1\n\nline2");
     }
 
     #[test]
@@ -390,7 +390,7 @@ fn should_leave_multiple_indent_levels() {
         // base indentation and should be preserved
         let s = "    line1\n\n        line2".to_string();
         let r = unindent(s.as_slice());
-        assert_eq!(r.as_slice(), "line1\n\n    line2");
+        assert_eq!(r, "line1\n\n    line2");
     }
 
     #[test]
@@ -402,13 +402,13 @@ fn should_ignore_first_line_indent() {
         //          and continue here"]
         let s = "line1\n    line2".to_string();
         let r = unindent(s.as_slice());
-        assert_eq!(r.as_slice(), "line1\nline2");
+        assert_eq!(r, "line1\nline2");
     }
 
     #[test]
     fn should_not_ignore_first_line_indent_in_a_single_line_para() {
         let s = "line1\n\n    line2".to_string();
         let r = unindent(s.as_slice());
-        assert_eq!(r.as_slice(), "line1\n\n    line2");
+        assert_eq!(r, "line1\n\n    line2");
     }
 }
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 7ca7ae4b21149ade1afe461deaf8e821a93ea974..5759adf32440ee90ed0753674e4fda87621d5b78 100644 (file)
@@ -280,7 +280,7 @@ pub fn add_test(&mut self, test: String,
             desc: testing::TestDesc {
                 name: testing::DynTestName(name),
                 ignore: should_ignore,
-                should_fail: false, // compiler failures are test failures
+                should_fail: testing::ShouldFail::No, // compiler failures are test failures
             },
             testfn: testing::DynTestFn(proc() {
                 runtest(test.as_slice(),
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 b7d8885a5f99313406af29bb65b8d8f999ac2b39..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,63 +303,79 @@ 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() {
-        assert_eq!("".as_bytes().to_base64(STANDARD), "".to_string());
-        assert_eq!("f".as_bytes().to_base64(STANDARD), "Zg==".to_string());
-        assert_eq!("fo".as_bytes().to_base64(STANDARD), "Zm8=".to_string());
-        assert_eq!("foo".as_bytes().to_base64(STANDARD), "Zm9v".to_string());
-        assert_eq!("foob".as_bytes().to_base64(STANDARD), "Zm9vYg==".to_string());
-        assert_eq!("fooba".as_bytes().to_base64(STANDARD), "Zm9vYmE=".to_string());
-        assert_eq!("foobar".as_bytes().to_base64(STANDARD), "Zm9vYmFy".to_string());
+        assert_eq!("".as_bytes().to_base64(STANDARD), "");
+        assert_eq!("f".as_bytes().to_base64(STANDARD), "Zg==");
+        assert_eq!("fo".as_bytes().to_base64(STANDARD), "Zm8=");
+        assert_eq!("foo".as_bytes().to_base64(STANDARD), "Zm9v");
+        assert_eq!("foob".as_bytes().to_base64(STANDARD), "Zm9vYg==");
+        assert_eq!("fooba".as_bytes().to_base64(STANDARD), "Zm9vYmE=");
+        assert_eq!("foobar".as_bytes().to_base64(STANDARD), "Zm9vYmFy");
     }
 
     #[test]
-    fn test_to_base64_line_break() {
+    fn test_to_base64_crlf_line_break() {
         assert!(![0u8, ..1000].to_base64(Config {line_length: None, ..STANDARD})
-                              .as_slice()
                               .contains("\r\n"));
-        assert_eq!("foobar".as_bytes().to_base64(Config {line_length: Some(4),
-                                                         ..STANDARD}),
-                   "Zm9v\r\nYmFy".to_string());
+        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".to_string());
-        assert_eq!("fo".as_bytes().to_base64(Config {pad: false, ..STANDARD}), "Zm8".to_string());
+        assert_eq!("f".as_bytes().to_base64(Config {pad: false, ..STANDARD}), "Zg");
+        assert_eq!("fo".as_bytes().to_base64(Config {pad: false, ..STANDARD}), "Zm8");
     }
 
     #[test]
     fn test_to_base64_url_safe() {
-        assert_eq!([251, 255].to_base64(URL_SAFE), "-_8".to_string());
-        assert_eq!([251, 255].to_base64(STANDARD), "+/8=".to_string());
+        assert_eq!([251, 255].to_base64(URL_SAFE), "-_8");
+        assert_eq!([251, 255].to_base64(STANDARD), "+/8=");
     }
 
     #[test]
     fn test_from_base64_basic() {
-        assert_eq!("".from_base64().unwrap().as_slice(), "".as_bytes());
-        assert_eq!("Zg==".from_base64().unwrap().as_slice(), "f".as_bytes());
-        assert_eq!("Zm8=".from_base64().unwrap().as_slice(), "fo".as_bytes());
-        assert_eq!("Zm9v".from_base64().unwrap().as_slice(), "foo".as_bytes());
-        assert_eq!("Zm9vYg==".from_base64().unwrap().as_slice(), "foob".as_bytes());
-        assert_eq!("Zm9vYmE=".from_base64().unwrap().as_slice(), "fooba".as_bytes());
-        assert_eq!("Zm9vYmFy".from_base64().unwrap().as_slice(), "foobar".as_bytes());
+        assert_eq!("".from_base64().unwrap(), b"");
+        assert_eq!("Zg==".from_base64().unwrap(), b"f");
+        assert_eq!("Zm8=".from_base64().unwrap(), b"fo");
+        assert_eq!("Zm9v".from_base64().unwrap(), b"foo");
+        assert_eq!("Zm9vYg==".from_base64().unwrap(), b"foob");
+        assert_eq!("Zm9vYmE=".from_base64().unwrap(), b"fooba");
+        assert_eq!("Zm9vYmFy".from_base64().unwrap(), b"foobar");
     }
 
     #[test]
     fn test_from_base64_bytes() {
-        assert_eq!(b"Zm9vYmFy".from_base64().unwrap().as_slice(), "foobar".as_bytes());
+        assert_eq!(b"Zm9vYmFy".from_base64().unwrap(), b"foobar");
     }
 
     #[test]
     fn test_from_base64_newlines() {
-        assert_eq!("Zm9v\r\nYmFy".from_base64().unwrap().as_slice(),
-                   "foobar".as_bytes());
-        assert_eq!("Zm9vYg==\r\n".from_base64().unwrap().as_slice(),
-                   "foob".as_bytes());
+        assert_eq!("Zm9v\r\nYmFy".from_base64().unwrap(),
+                   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]
@@ -364,13 +401,10 @@ fn test_base64_random() {
         for _ in range(0u, 1000) {
             let times = task_rng().gen_range(1u, 100);
             let v = Vec::from_fn(times, |_| random::<u8>());
-            assert_eq!(v.as_slice()
-                        .to_base64(STANDARD)
-                        .as_slice()
+            assert_eq!(v.to_base64(STANDARD)
                         .from_base64()
-                        .unwrap()
-                        .as_slice(),
-                       v.as_slice());
+                        .unwrap(),
+                       v);
         }
     }
 
@@ -390,7 +424,7 @@ pub fn bench_from_base64(b: &mut Bencher) {
                  ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン";
         let sb = s.as_bytes().to_base64(STANDARD);
         b.iter(|| {
-            sb.as_slice().from_base64().unwrap();
+            sb.from_base64().unwrap();
         });
         b.bytes = sb.len() as u64;
     }
index 2a3c410ba7c589912c5bd797377552bf7527b5b3..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 {
@@ -158,15 +160,15 @@ mod tests {
 
     #[test]
     pub fn test_to_hex() {
-        assert_eq!("foobar".as_bytes().to_hex(), "666f6f626172".to_string());
+        assert_eq!("foobar".as_bytes().to_hex(), "666f6f626172");
     }
 
     #[test]
     pub fn test_from_hex_okay() {
-        assert_eq!("666f6f626172".from_hex().unwrap().as_slice(),
-                   "foobar".as_bytes());
-        assert_eq!("666F6F626172".from_hex().unwrap().as_slice(),
-                   "foobar".as_bytes());
+        assert_eq!("666f6f626172".from_hex().unwrap(),
+                   b"foobar");
+        assert_eq!("666F6F626172".from_hex().unwrap(),
+                   b"foobar");
     }
 
     #[test]
@@ -182,8 +184,8 @@ pub fn test_from_hex_invalid_char() {
 
     #[test]
     pub fn test_from_hex_ignores_whitespace() {
-        assert_eq!("666f 6f6\r\n26172 ".from_hex().unwrap().as_slice(),
-                   "foobar".as_bytes());
+        assert_eq!("666f 6f6\r\n26172 ".from_hex().unwrap(),
+                   b"foobar");
     }
 
     #[test]
@@ -197,15 +199,11 @@ pub fn test_to_hex_all_bytes() {
     pub fn test_from_hex_all_bytes() {
         for i in range(0u, 256) {
             let ii: &[u8] = &[i as u8];
-            assert_eq!(format!("{:02x}", i as uint).as_slice()
-                                                   .from_hex()
-                                                   .unwrap()
-                                                   .as_slice(),
+            assert_eq!(format!("{:02x}", i as uint).from_hex()
+                                                   .unwrap(),
                        ii);
-            assert_eq!(format!("{:02X}", i as uint).as_slice()
-                                                   .from_hex()
-                                                   .unwrap()
-                                                   .as_slice(),
+            assert_eq!(format!("{:02X}", i as uint).from_hex()
+                                                   .unwrap(),
                        ii);
         }
     }
@@ -226,7 +224,7 @@ pub fn bench_from_hex(b: &mut Bencher) {
                  ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン";
         let sb = s.as_bytes().to_hex();
         b.iter(|| {
-            sb.as_slice().from_hex().unwrap();
+            sb.from_hex().unwrap();
         });
         b.bytes = sb.len() as u64;
     }
index fa82eb93faeec8df5d7eb14ffc9b479c6e6d690f..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)))
         }
     }
 
@@ -2039,14 +2037,14 @@ fn read_bool(&mut self) -> DecodeResult<bool> {
     fn read_char(&mut self) -> DecodeResult<char> {
         let s = try!(self.read_str());
         {
-            let mut it = s.as_slice().chars();
+            let mut it = s.chars();
             match (it.next(), it.next()) {
                 // exactly one character
                 (Some(c), None) => return Ok(c),
                 _ => ()
             }
         }
-        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,87 +2484,90 @@ fn test_from_str_trait() {
 
     #[test]
     fn test_write_null() {
-        assert_eq!(Null.to_string().into_string(), "null".to_string());
-        assert_eq!(Null.to_pretty_str().into_string(), "null".to_string());
+        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".to_string());
-        assert_eq!(U64(0).to_pretty_str().into_string(), "0".to_string());
+        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".to_string());
-        assert_eq!(U64(1234).to_pretty_str().into_string(), "1234".to_string());
+        assert_eq!(I64(-5678).to_string(), "-5678");
+        assert_eq!(I64(-5678).to_pretty_str(), "-5678");
 
-        assert_eq!(I64(-5678).to_string().into_string(), "-5678".to_string());
-        assert_eq!(I64(-5678).to_pretty_str().into_string(), "-5678".to_string());
+        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".to_string());
-        assert_eq!(F64(3.0).to_pretty_str().into_string(), "3".to_string());
+        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".to_string());
-        assert_eq!(F64(3.1).to_pretty_str().into_string(), "3.1".to_string());
+        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".to_string());
-        assert_eq!(F64(-1.5).to_pretty_str().into_string(), "-1.5".to_string());
+        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".to_string());
-        assert_eq!(F64(0.5).to_pretty_str().into_string(), "0.5".to_string());
+        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".to_string());
-        assert_eq!(F64(f64::NAN).to_pretty_str().into_string(), "null".to_string());
+        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".to_string());
-        assert_eq!(F64(f64::INFINITY).to_pretty_str().into_string(), "null".to_string());
+        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".to_string());
-        assert_eq!(F64(f64::NEG_INFINITY).to_pretty_str().into_string(), "null".to_string());
+        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(), "\"\"".to_string());
-        assert_eq!(String("".to_string()).to_pretty_str().into_string(), "\"\"".to_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\"".to_string());
-        assert_eq!(String("foo".to_string()).to_pretty_str().into_string(), "\"foo\"".to_string());
+        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".to_string());
-        assert_eq!(Boolean(true).to_pretty_str().into_string(), "true".to_string());
+        assert_eq!(Boolean(true).to_string(), "true");
+        assert_eq!(Boolean(true).to_pretty_str(), "true");
 
-        assert_eq!(Boolean(false).to_string().into_string(), "false".to_string());
-        assert_eq!(Boolean(false).to_pretty_str().into_string(), "false".to_string());
+        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(), "[]".to_string());
-        assert_eq!(Array(vec![]).to_pretty_str().into_string(), "[]".to_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]".to_string());
+        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\
-            ]".to_string()
+            ]"
         );
 
         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(),
-            "[false,null,[\"foo\\nbar\",3.5]]".to_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  \
@@ -2575,47 +2576,47 @@ fn test_write_array() {
                     \"foo\\nbar\",\n    \
                     3.5\n  \
                 ]\n\
-            ]".to_string()
+            ]"
         );
     }
 
     #[test]
     fn test_write_object() {
-        assert_eq!(mk_object(&[]).to_string().into_string(), "{}".to_string());
-        assert_eq!(mk_object(&[]).to_pretty_str().into_string(), "{}".to_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\":true}".to_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\
-            }".to_string()
+            }"
         );
 
         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\"},\
                     {\"d\":\"\"}\
                 ]\
-            }".to_string()
+            }"
         );
         assert_eq!(
-            complex_obj.to_pretty_str().into_string(),
+            complex_obj.to_pretty_str(),
             "\
             {\n  \
                 \"b\": [\n    \
@@ -2626,14 +2627,14 @@ fn test_write_object() {
                         \"d\": \"\"\n    \
                     }\n  \
                 ]\n\
-            }".to_string()
+            }"
         );
 
         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()))])
             ]))
         ]);
 
@@ -2660,23 +2661,23 @@ fn test_write_enum() {
                 let mut encoder = Encoder::new(writer);
                 animal.encode(&mut encoder).unwrap();
             }),
-            "\"Dog\"".to_string()
+            "\"Dog\""
         );
         assert_eq!(
             with_str_writer(|writer| {
                 let mut encoder = PrettyEncoder::new(writer);
                 animal.encode(&mut encoder).unwrap();
             }),
-            "\"Dog\"".to_string()
+            "\"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);
                 animal.encode(&mut encoder).unwrap();
             }),
-            "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}".to_string()
+            "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}"
         );
         assert_eq!(
             with_str_writer(|writer| {
@@ -2689,25 +2690,25 @@ fn test_write_enum() {
                  \"Henry\",\n    \
                  349\n  \
                ]\n\
-             }".to_string()
+             }"
         );
     }
 
     #[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\"".to_string());
+        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();
         });
-        assert_eq!(s, "\"jodhpurs\"".to_string());
+        assert_eq!(s, "\"jodhpurs\"");
     }
 
     #[test]
@@ -2717,13 +2718,13 @@ fn test_write_none() {
             let mut encoder = Encoder::new(writer);
             value.encode(&mut encoder).unwrap();
         });
-        assert_eq!(s, "null".to_string());
+        assert_eq!(s, "null");
 
         let s = with_str_writer(|writer| {
             let mut encoder = Encoder::new(writer);
             value.encode(&mut encoder).unwrap();
         });
-        assert_eq!(s, "null".to_string());
+        assert_eq!(s, "null");
     }
 
     #[test]
@@ -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]
@@ -2860,7 +2864,7 @@ fn test_decode_str() {
 
         for &(i, o) in s.iter() {
             let v: string::String = super::decode(i).unwrap();
-            assert_eq!(v.as_slice(), o);
+            assert_eq!(v, o);
         }
     }
 
@@ -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]},"#);
@@ -3778,7 +3782,7 @@ fn big_json() -> string::String {
     fn bench_streaming_large(b: &mut Bencher) {
         let src = big_json();
         b.iter( || {
-            let mut parser = Parser::new(src.as_slice().chars());
+            let mut parser = Parser::new(src.chars());
             loop {
                 match parser.next() {
                     None => return,
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 8fc3c23e88f153dc203ef25a77b5984b2615a3a1..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]
@@ -678,16 +681,16 @@ fn test_ascii_vec() {
         assert_eq!(test.to_ascii(), b);
         assert_eq!("( ;".to_ascii(), b);
         let v = vec![40u8, 32u8, 59u8];
-        assert_eq!(v.as_slice().to_ascii(), b);
-        assert_eq!("( ;".to_string().as_slice().to_ascii(), b);
+        assert_eq!(v.to_ascii(), b);
+        assert_eq!("( ;".to_string().to_ascii(), b);
 
-        assert_eq!("abCDef&?#".to_ascii().to_lowercase().into_string(), "abcdef&?#".to_string());
-        assert_eq!("abCDef&?#".to_ascii().to_uppercase().into_string(), "ABCDEF&?#".to_string());
+        assert_eq!("abCDef&?#".to_ascii().to_lowercase().into_string(), "abcdef&?#");
+        assert_eq!("abCDef&?#".to_ascii().to_uppercase().into_string(), "ABCDEF&?#");
 
-        assert_eq!("".to_ascii().to_lowercase().into_string(), "".to_string());
-        assert_eq!("YMCA".to_ascii().to_lowercase().into_string(), "ymca".to_string());
+        assert_eq!("".to_ascii().to_lowercase().into_string(), "");
+        assert_eq!("YMCA".to_ascii().to_lowercase().into_string(), "ymca");
         let mixed = "abcDEFxyz:.;".to_ascii();
-        assert_eq!(mixed.to_uppercase().into_string(), "ABCDEFXYZ:.;".to_string());
+        assert_eq!(mixed.to_uppercase().into_string(), "ABCDEFXYZ:.;");
 
         assert!("aBcDeF&?#".to_ascii().eq_ignore_case("AbCdEf&?#".to_ascii()));
 
@@ -699,12 +702,12 @@ fn test_ascii_vec() {
 
     #[test]
     fn test_ascii_vec_ng() {
-        assert_eq!("abCDef&?#".to_ascii().to_lowercase().into_string(), "abcdef&?#".to_string());
-        assert_eq!("abCDef&?#".to_ascii().to_uppercase().into_string(), "ABCDEF&?#".to_string());
-        assert_eq!("".to_ascii().to_lowercase().into_string(), "".to_string());
-        assert_eq!("YMCA".to_ascii().to_lowercase().into_string(), "ymca".to_string());
+        assert_eq!("abCDef&?#".to_ascii().to_lowercase().into_string(), "abcdef&?#");
+        assert_eq!("abCDef&?#".to_ascii().to_uppercase().into_string(), "ABCDEF&?#");
+        assert_eq!("".to_ascii().to_lowercase().into_string(), "");
+        assert_eq!("YMCA".to_ascii().to_lowercase().into_string(), "ymca");
         let mixed = "abcDEFxyz:.;".to_ascii();
-        assert_eq!(mixed.to_uppercase().into_string(), "ABCDEFXYZ:.;".to_string());
+        assert_eq!(mixed.to_uppercase().into_string(), "ABCDEFXYZ:.;");
     }
 
     #[test]
@@ -721,8 +724,8 @@ fn test_ascii_as_str() {
 
     #[test]
     fn test_ascii_into_string() {
-        assert_eq!(vec2ascii![40, 32, 59].into_string(), "( ;".to_string());
-        assert_eq!(vec2ascii!(40, 32, 59).into_string(), "( ;".to_string());
+        assert_eq!(vec2ascii![40, 32, 59].into_string(), "( ;");
+        assert_eq!(vec2ascii!(40, 32, 59).into_string(), "( ;");
     }
 
     #[test]
@@ -774,14 +777,14 @@ fn test_opt() {
 
     #[test]
     fn test_to_ascii_upper() {
-        assert_eq!("url()URL()uRl()ürl".to_ascii_upper(), "URL()URL()URL()üRL".to_string());
-        assert_eq!("hıKß".to_ascii_upper(), "HıKß".to_string());
+        assert_eq!("url()URL()uRl()ürl".to_ascii_upper(), "URL()URL()URL()üRL");
+        assert_eq!("hıKß".to_ascii_upper(), "HıKß");
 
         let mut i = 0;
         while i <= 500 {
             let upper = if 'a' as u32 <= i && i <= 'z' as u32 { i + 'A' as u32 - 'a' as u32 }
                         else { i };
-            assert_eq!((from_u32(i).unwrap()).to_string().as_slice().to_ascii_upper(),
+            assert_eq!((from_u32(i).unwrap()).to_string().to_ascii_upper(),
                        (from_u32(upper).unwrap()).to_string())
             i += 1;
         }
@@ -789,15 +792,15 @@ fn test_to_ascii_upper() {
 
     #[test]
     fn test_to_ascii_lower() {
-        assert_eq!("url()URL()uRl()Ürl".to_ascii_lower(), "url()url()url()Ürl".to_string());
+        assert_eq!("url()URL()uRl()Ürl".to_ascii_lower(), "url()url()url()Ürl");
         // Dotted capital I, Kelvin sign, Sharp S.
-        assert_eq!("HİKß".to_ascii_lower(), "hİKß".to_string());
+        assert_eq!("HİKß".to_ascii_lower(), "hİKß");
 
         let mut i = 0;
         while i <= 500 {
             let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 }
                         else { i };
-            assert_eq!((from_u32(i).unwrap()).to_string().as_slice().to_ascii_lower(),
+            assert_eq!((from_u32(i).unwrap()).to_string().to_ascii_lower(),
                        (from_u32(lower).unwrap()).to_string())
             i += 1;
         }
@@ -807,7 +810,7 @@ fn test_to_ascii_lower() {
     fn test_into_ascii_upper() {
         assert_eq!(("url()URL()uRl()ürl".to_string()).into_ascii_upper(),
                    "URL()URL()URL()üRL".to_string());
-        assert_eq!(("hıKß".to_string()).into_ascii_upper(), "HıKß".to_string());
+        assert_eq!(("hıKß".to_string()).into_ascii_upper(), "HıKß");
 
         let mut i = 0;
         while i <= 500 {
@@ -822,9 +825,9 @@ fn test_into_ascii_upper() {
     #[test]
     fn test_into_ascii_lower() {
         assert_eq!(("url()URL()uRl()Ürl".to_string()).into_ascii_lower(),
-                   "url()url()url()Ürl".to_string());
+                   "url()url()url()Ürl");
         // Dotted capital I, Kelvin sign, Sharp S.
-        assert_eq!(("HİKß".to_string()).into_ascii_lower(), "hİKß".to_string());
+        assert_eq!(("HİKß".to_string()).into_ascii_lower(), "hİKß");
 
         let mut i = 0;
         while i <= 500 {
@@ -851,7 +854,7 @@ fn test_eq_ignore_ascii_case() {
             let c = i;
             let lower = if 'A' as u32 <= c && c <= 'Z' as u32 { c + 'a' as u32 - 'A' as u32 }
                         else { c };
-            assert!((from_u32(i).unwrap()).to_string().as_slice().eq_ignore_ascii_case(
+            assert!((from_u32(i).unwrap()).to_string().eq_ignore_ascii_case(
                     (from_u32(lower).unwrap()).to_string().as_slice()));
             i += 1;
         }
@@ -860,12 +863,12 @@ fn test_eq_ignore_ascii_case() {
     #[test]
     fn test_to_string() {
         let s = Ascii{ chr: b't' }.to_string();
-        assert_eq!(s, "t".to_string());
+        assert_eq!(s, "t");
     }
 
     #[test]
     fn test_show() {
         let c = Ascii { chr: b't' };
-        assert_eq!(format!("{}", c), "t".to_string());
+        assert_eq!(format!("{}", c), "t");
     }
 }
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 8f879bd50d0b3944acbcc41e79b24a6c9a7e8e08..a8dce232d26d576f72c4dc0bdfdf1c055579323d 100644 (file)
@@ -1548,7 +1548,7 @@ fn test_drops() {
 
             DROP_VECTOR.with(|v| {
                 for i in range(0u, 200) {
-                    assert_eq!(v.borrow().as_slice()[i], 0);
+                    assert_eq!(v.borrow()[i], 0);
                 }
             });
 
@@ -1560,7 +1560,7 @@ fn test_drops() {
 
             DROP_VECTOR.with(|v| {
                 for i in range(0u, 200) {
-                    assert_eq!(v.borrow().as_slice()[i], 1);
+                    assert_eq!(v.borrow()[i], 1);
                 }
             });
 
@@ -1571,27 +1571,27 @@ fn test_drops() {
                 assert!(v.is_some());
 
                 DROP_VECTOR.with(|v| {
-                    assert_eq!(v.borrow().as_slice()[i], 1);
-                    assert_eq!(v.borrow().as_slice()[i+100], 1);
+                    assert_eq!(v.borrow()[i], 1);
+                    assert_eq!(v.borrow()[i+100], 1);
                 });
             }
 
             DROP_VECTOR.with(|v| {
                 for i in range(0u, 50) {
-                    assert_eq!(v.borrow().as_slice()[i], 0);
-                    assert_eq!(v.borrow().as_slice()[i+100], 0);
+                    assert_eq!(v.borrow()[i], 0);
+                    assert_eq!(v.borrow()[i+100], 0);
                 }
 
                 for i in range(50u, 100) {
-                    assert_eq!(v.borrow().as_slice()[i], 1);
-                    assert_eq!(v.borrow().as_slice()[i+100], 1);
+                    assert_eq!(v.borrow()[i], 1);
+                    assert_eq!(v.borrow()[i+100], 1);
                 }
             });
         }
 
         DROP_VECTOR.with(|v| {
             for i in range(0u, 200) {
-                assert_eq!(v.borrow().as_slice()[i], 0);
+                assert_eq!(v.borrow()[i], 0);
             }
         });
     }
@@ -1607,7 +1607,7 @@ fn test_move_iter_drops() {
 
             DROP_VECTOR.with(|v| {
                 for i in range(0u, 200) {
-                    assert_eq!(v.borrow().as_slice()[i], 0);
+                    assert_eq!(v.borrow()[i], 0);
                 }
             });
 
@@ -1619,7 +1619,7 @@ fn test_move_iter_drops() {
 
             DROP_VECTOR.with(|v| {
                 for i in range(0u, 200) {
-                    assert_eq!(v.borrow().as_slice()[i], 1);
+                    assert_eq!(v.borrow()[i], 1);
                 }
             });
 
@@ -1634,7 +1634,7 @@ fn test_move_iter_drops() {
 
             DROP_VECTOR.with(|v| {
                 for i in range(0u, 200) {
-                    assert_eq!(v.borrow().as_slice()[i], 1);
+                    assert_eq!(v.borrow()[i], 1);
                 }
             });
 
@@ -1642,11 +1642,11 @@ fn test_move_iter_drops() {
 
             DROP_VECTOR.with(|v| {
                 let nk = range(0u, 100).filter(|&i| {
-                    v.borrow().as_slice()[i] == 1
+                    v.borrow()[i] == 1
                 }).count();
 
                 let nv = range(0u, 100).filter(|&i| {
-                    v.borrow().as_slice()[i+100] == 1
+                    v.borrow()[i+100] == 1
                 }).count();
 
                 assert_eq!(nk, 50);
@@ -1656,7 +1656,7 @@ fn test_move_iter_drops() {
 
         DROP_VECTOR.with(|v| {
             for i in range(0u, 200) {
-                assert_eq!(v.borrow().as_slice()[i], 0);
+                assert_eq!(v.borrow()[i], 0);
             }
         });
     }
@@ -1905,8 +1905,8 @@ fn test_show() {
 
         let map_str = format!("{}", map);
 
-        assert!(map_str == "{1: 2, 3: 4}".to_string() || map_str == "{3: 4, 1: 2}".to_string());
-        assert_eq!(format!("{}", empty), "{}".to_string());
+        assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}");
+        assert_eq!(format!("{}", empty), "{}");
     }
 
     #[test]
index fd32d207e79e095ad94f14b94d819678c6b67ab8..b3ccfdbb47cceaad5f883e4cfe4406b0b8f83341 100644 (file)
@@ -827,7 +827,7 @@ fn test_move_iter() {
         };
 
         let v = hs.into_iter().collect::<Vec<char>>();
-        assert!(['a', 'b'][] == v.as_slice() || ['b', 'a'][] == v.as_slice());
+        assert!(['a', 'b'] == v || ['b', 'a'] == v);
     }
 
     #[test]
@@ -862,7 +862,7 @@ fn test_show() {
 
         let set_str = format!("{}", set);
 
-        assert!(set_str == "{1, 2}".to_string() || set_str == "{2, 1}".to_string());
-        assert_eq!(format!("{}", empty), "{}".to_string());
+        assert!(set_str == "{1, 2}" || set_str == "{2, 1}");
+        assert_eq!(format!("{}", empty), "{}");
     }
 }
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 adbc135364be7fc73e8f6b5103414943fcbc7596..6caa2f7b4da6a06f249f002a113bc6fdd71a6be7 100644 (file)
@@ -447,15 +447,15 @@ fn test_to_string() {
         cache.insert(1, 10);
         cache.insert(2, 20);
         cache.insert(3, 30);
-        assert_eq!(cache.to_string(), "{3: 30, 2: 20, 1: 10}".to_string());
+        assert_eq!(cache.to_string(), "{3: 30, 2: 20, 1: 10}");
         cache.insert(2, 22);
-        assert_eq!(cache.to_string(), "{2: 22, 3: 30, 1: 10}".to_string());
+        assert_eq!(cache.to_string(), "{2: 22, 3: 30, 1: 10}");
         cache.insert(6, 60);
-        assert_eq!(cache.to_string(), "{6: 60, 2: 22, 3: 30}".to_string());
+        assert_eq!(cache.to_string(), "{6: 60, 2: 22, 3: 30}");
         cache.get(&3);
-        assert_eq!(cache.to_string(), "{3: 30, 6: 60, 2: 22}".to_string());
+        assert_eq!(cache.to_string(), "{3: 30, 6: 60, 2: 22}");
         cache.set_capacity(2);
-        assert_eq!(cache.to_string(), "{3: 30, 6: 60}".to_string());
+        assert_eq!(cache.to_string(), "{3: 30, 6: 60}");
     }
 
     #[test]
@@ -466,6 +466,6 @@ fn test_clear() {
         cache.clear();
         assert!(cache.get(&1).is_none());
         assert!(cache.get(&2).is_none());
-        assert_eq!(cache.to_string(), "{}".to_string());
+        assert_eq!(cache.to_string(), "{}");
     }
 }
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 6a2047d1cef30dffe4383168dd65084ac645cbd5..d0c9df9d914e764d72f526712d912f6e73188f5d 100644 (file)
 pub use core::fmt::{Argument, Arguments, write, radix, Radix, RadixFmt};
 
 #[doc(hidden)]
-pub use core::fmt::{argument, argumentstr, argumentuint};
+pub use core::fmt::{argument, argumentuint};
 
 /// The format function takes a precompiled format string and a list of
 /// arguments, to return the resulting formatted string.
index 0b2c6843c968e33c22566313cc8eac64b4e940b4..a8de7356fe7d1a762ceb14d21eb3751f44be1916 100644 (file)
@@ -450,30 +450,30 @@ fn test_buffered_reader() {
         let nread = reader.read(&mut buf);
         assert_eq!(Ok(3), nread);
         let b: &[_] = &[5, 6, 7];
-        assert_eq!(buf.as_slice(), b);
+        assert_eq!(buf, b);
 
         let mut buf = [0, 0];
         let nread = reader.read(&mut buf);
         assert_eq!(Ok(2), nread);
         let b: &[_] = &[0, 1];
-        assert_eq!(buf.as_slice(), b);
+        assert_eq!(buf, b);
 
         let mut buf = [0];
         let nread = reader.read(&mut buf);
         assert_eq!(Ok(1), nread);
         let b: &[_] = &[2];
-        assert_eq!(buf.as_slice(), b);
+        assert_eq!(buf, b);
 
         let mut buf = [0, 0, 0];
         let nread = reader.read(&mut buf);
         assert_eq!(Ok(1), nread);
         let b: &[_] = &[3, 0, 0];
-        assert_eq!(buf.as_slice(), b);
+        assert_eq!(buf, b);
 
         let nread = reader.read(&mut buf);
         assert_eq!(Ok(1), nread);
         let b: &[_] = &[4, 0, 0];
-        assert_eq!(buf.as_slice(), b);
+        assert_eq!(buf, b);
 
         assert!(reader.read(&mut buf).is_err());
     }
index 3de0a7be95e8bc8500d5db75dbe5c3584a8c7119..4ec1a3764db66ca94ec9ce6ce682cfbbbc105a18 100644 (file)
@@ -176,28 +176,28 @@ fn test_rx_reader() {
 
         assert_eq!(Ok(3), reader.read(&mut buf));
         let a: &[u8] = &[1,2,3];
-        assert_eq!(a, buf.as_slice());
+        assert_eq!(a, buf);
 
         assert_eq!(Ok(3), reader.read(&mut buf));
         let a: &[u8] = &[4,5,6];
-        assert_eq!(a, buf.as_slice());
+        assert_eq!(a, buf);
 
         assert_eq!(Ok(2), reader.read(&mut buf));
         let a: &[u8] = &[7,8,6];
-        assert_eq!(a, buf.as_slice());
+        assert_eq!(a, buf);
 
         match reader.read(buf.as_mut_slice()) {
             Ok(..) => panic!(),
             Err(e) => assert_eq!(e.kind, io::EndOfFile),
         }
-        assert_eq!(a, buf.as_slice());
+        assert_eq!(a, buf);
 
         // Ensure it continues to panic in the same way.
         match reader.read(buf.as_mut_slice()) {
             Ok(..) => panic!(),
             Err(e) => assert_eq!(e.kind, io::EndOfFile),
         }
-        assert_eq!(a, buf.as_slice());
+        assert_eq!(a, buf);
     }
 
     #[test]
index 86b2dc4d94053a8bba0c6efb709970d29157fd1e..5611c6526ad3d58267e637d598cbaf6a4e978778 100644 (file)
@@ -838,7 +838,7 @@ macro_rules! check( ($e:expr) => (
     macro_rules! error( ($e:expr, $s:expr) => (
         match $e {
             Ok(_) => panic!("Unexpected success. Should've been: {}", $s),
-            Err(ref err) => assert!(err.to_string().as_slice().contains($s.as_slice()),
+            Err(ref err) => assert!(err.to_string().contains($s.as_slice()),
                                     format!("`{}` did not contain `{}`", err, $s))
         }
     ) )
@@ -996,7 +996,7 @@ fn file_test_io_seek_and_write() {
         }
         check!(unlink(filename));
         let read_str = str::from_utf8(&read_mem).unwrap();
-        assert!(read_str.as_slice() == final_msg.as_slice());
+        assert!(read_str == final_msg);
     }
 
     #[test]
@@ -1104,7 +1104,7 @@ fn file_test_directoryinfo_readdir() {
             let f = dir.join(format!("{}.txt", n));
             let mut w = check!(File::create(&f));
             let msg_str = format!("{}{}", prefix, n.to_string());
-            let msg = msg_str.as_slice().as_bytes();
+            let msg = msg_str.as_bytes();
             check!(w.write(msg));
         }
         let files = check!(readdir(dir));
index 43e02d62b0b5aa800e754b4f7ca1c9510c922166..4dc87278e2bbc002a93ba10698810872291c9ba9 100644 (file)
@@ -444,7 +444,7 @@ fn test_buf_writer() {
             assert_eq!(writer.write(&[10]).unwrap_err().kind, io::EndOfFile);
         }
         let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
-        assert_eq!(buf.as_slice(), b);
+        assert_eq!(buf, b);
     }
 
     #[test]
@@ -473,7 +473,7 @@ fn test_buf_writer_seek() {
 
         }
         let b: &[_] = &[1, 3, 2, 0, 0, 0, 0, 4];
-        assert_eq!(buf.as_slice(), b);
+        assert_eq!(buf, b);
     }
 
     #[test]
@@ -498,12 +498,12 @@ fn test_mem_reader() {
         assert_eq!(reader.read(&mut buf), Ok(1));
         assert_eq!(reader.tell(), Ok(1));
         let b: &[_] = &[0];
-        assert_eq!(buf.as_slice(), b);
+        assert_eq!(buf, b);
         let mut buf = [0, ..4];
         assert_eq!(reader.read(&mut buf), Ok(4));
         assert_eq!(reader.tell(), Ok(5));
         let b: &[_] = &[1, 2, 3, 4];
-        assert_eq!(buf.as_slice(), b);
+        assert_eq!(buf, b);
         assert_eq!(reader.read(&mut buf), Ok(3));
         let b: &[_] = &[5, 6, 7];
         assert_eq!(buf[0..3], b);
@@ -551,12 +551,12 @@ fn test_buf_reader() {
         assert_eq!(reader.read(&mut buf), Ok(1));
         assert_eq!(reader.tell(), Ok(1));
         let b: &[_] = &[0];
-        assert_eq!(buf.as_slice(), b);
+        assert_eq!(buf, b);
         let mut buf = [0, ..4];
         assert_eq!(reader.read(&mut buf), Ok(4));
         assert_eq!(reader.tell(), Ok(5));
         let b: &[_] = &[1, 2, 3, 4];
-        assert_eq!(buf.as_slice(), b);
+        assert_eq!(buf, b);
         assert_eq!(reader.read(&mut buf), Ok(3));
         let b: &[_] = &[5, 6, 7];
         assert_eq!(buf[0..3], b);
@@ -592,7 +592,7 @@ fn test_write_strings() {
         writer.write_line("testing").unwrap();
         writer.write_str("testing").unwrap();
         let mut r = BufReader::new(writer.get_ref());
-        assert_eq!(r.read_to_string().unwrap(), "testingtesting\ntesting".to_string());
+        assert_eq!(r.read_to_string().unwrap(), "testingtesting\ntesting");
     }
 
     #[test]
@@ -602,7 +602,7 @@ fn test_write_char() {
         writer.write_char('\n').unwrap();
         writer.write_char('ệ').unwrap();
         let mut r = BufReader::new(writer.get_ref());
-        assert_eq!(r.read_to_string().unwrap(), "a\nệ".to_string());
+        assert_eq!(r.read_to_string().unwrap(), "a\nệ");
     }
 
     #[test]
@@ -652,15 +652,15 @@ fn io_read_at_least() {
         let mut buf = [0, ..3];
         assert!(r.read_at_least(buf.len(), &mut buf).is_ok());
         let b: &[_] = &[1, 2, 3];
-        assert_eq!(buf.as_slice(), b);
+        assert_eq!(buf, b);
         assert!(r.read_at_least(0, buf[mut ..0]).is_ok());
-        assert_eq!(buf.as_slice(), b);
+        assert_eq!(buf, b);
         assert!(r.read_at_least(buf.len(), &mut buf).is_ok());
         let b: &[_] = &[4, 5, 6];
-        assert_eq!(buf.as_slice(), b);
+        assert_eq!(buf, b);
         assert!(r.read_at_least(buf.len(), &mut buf).is_err());
         let b: &[_] = &[7, 8, 6];
-        assert_eq!(buf.as_slice(), b);
+        assert_eq!(buf, b);
     }
 
     fn do_bench_mem_writer(b: &mut Bencher, times: uint, len: uint) {
@@ -757,7 +757,7 @@ fn bench_buf_reader(b: &mut Bencher) {
                 for _i in range(0u, 10) {
                     let mut buf = [0 as u8, .. 10];
                     rdr.read(&mut buf).unwrap();
-                    assert_eq!(buf.as_slice(), [5, .. 10].as_slice());
+                    assert_eq!(buf, [5, .. 10]);
                 }
             }
         });
index e0857fd27ffdf35a0649cd60dedd87bfdbda3d2e..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;
 use result::Result;
 use result::Result::{Ok, Err};
 use sys;
-use slice::{AsSlice, SlicePrelude};
-use str::{Str, StrPrelude};
+use slice::SlicePrelude;
+use str::StrPrelude;
 use str;
 use string::String;
 use uint;
@@ -318,7 +319,7 @@ impl IoError {
     pub fn from_errno(errno: uint, detail: bool) -> IoError {
         let mut err = sys::decode_error(errno as i32);
         if detail && err.kind == OtherIoError {
-            err.detail = Some(os::error_string(errno).as_slice().chars()
+            err.detail = Some(os::error_string(errno).chars()
                                  .map(|c| c.to_lowercase()).collect())
         }
         err
@@ -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() }
@@ -2007,14 +2024,14 @@ fn test_push_at_least() {
     fn test_show() {
         use super::*;
 
-        assert_eq!(format!("{}", USER_READ), "0400".to_string());
-        assert_eq!(format!("{}", USER_FILE), "0644".to_string());
-        assert_eq!(format!("{}", USER_EXEC), "0755".to_string());
-        assert_eq!(format!("{}", USER_RWX),  "0700".to_string());
-        assert_eq!(format!("{}", GROUP_RWX), "0070".to_string());
-        assert_eq!(format!("{}", OTHER_RWX), "0007".to_string());
-        assert_eq!(format!("{}", ALL_PERMISSIONS), "0777".to_string());
-        assert_eq!(format!("{}", USER_READ | USER_WRITE | OTHER_WRITE), "0602".to_string());
+        assert_eq!(format!("{}", USER_READ), "0400");
+        assert_eq!(format!("{}", USER_FILE), "0644");
+        assert_eq!(format!("{}", USER_EXEC), "0755");
+        assert_eq!(format!("{}", USER_RWX),  "0700");
+        assert_eq!(format!("{}", GROUP_RWX), "0070");
+        assert_eq!(format!("{}", OTHER_RWX), "0007");
+        assert_eq!(format!("{}", ALL_PERMISSIONS), "0777");
+        assert_eq!(format!("{}", USER_READ | USER_WRITE | OTHER_WRITE), "0602");
     }
 
     fn _ensure_buffer_is_object_safe<T: Buffer>(x: &T) -> &Buffer {
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 9c0fbbe274b3eb5bbeee9b1c884861f8a6b7a445..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 {
@@ -641,10 +646,10 @@ fn test_from_str_socket_addr() {
     #[test]
     fn ipv6_addr_to_string() {
         let a1 = Ipv6Addr(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x280);
-        assert!(a1.to_string() == "::ffff:192.0.2.128".to_string() ||
-                a1.to_string() == "::FFFF:192.0.2.128".to_string());
+        assert!(a1.to_string() == "::ffff:192.0.2.128" ||
+                a1.to_string() == "::FFFF:192.0.2.128");
         assert_eq!(Ipv6Addr(8, 9, 10, 11, 12, 13, 14, 15).to_string(),
-                   "8:9:a:b:c:d:e:f".to_string());
+                   "8:9:a:b:c:d:e:f");
     }
 
     #[test]
index d4d24c1e12fc88449391980fe6f56358cc424092..c46a6e82e448661d3181b0f29535377fc1498760 100644 (file)
@@ -236,8 +236,8 @@ fn get_env_map<'a>(&'a mut self) -> &'a mut  EnvMap {
                 // if the env is currently just inheriting from the parent's,
                 // materialize the parent's env into a hashtable.
                 self.env = Some(os::env_as_bytes().into_iter()
-                                   .map(|(k, v)| (EnvKey(k.as_slice().to_c_str()),
-                                                  v.as_slice().to_c_str()))
+                                   .map(|(k, v)| (EnvKey(k.to_c_str()),
+                                                  v.to_c_str()))
                                    .collect());
                 self.env.as_mut().unwrap()
             }
@@ -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 {
@@ -810,7 +814,7 @@ pub fn run_output(cmd: Command) -> String {
     fn stdout_works() {
         let mut cmd = Command::new("echo");
         cmd.arg("foobar").stdout(CreatePipe(false, true));
-        assert_eq!(run_output(cmd), "foobar\n".to_string());
+        assert_eq!(run_output(cmd), "foobar\n");
     }
 
     #[cfg(all(unix, not(target_os="android")))]
@@ -820,7 +824,7 @@ fn set_cwd_works() {
         cmd.arg("-c").arg("pwd")
            .cwd(&Path::new("/"))
            .stdout(CreatePipe(false, true));
-        assert_eq!(run_output(cmd), "/\n".to_string());
+        assert_eq!(run_output(cmd), "/\n");
     }
 
     #[cfg(all(unix, not(target_os="android")))]
@@ -835,7 +839,7 @@ fn stdin_works() {
         drop(p.stdin.take());
         let out = read_all(p.stdout.as_mut().unwrap() as &mut Reader);
         assert!(p.wait().unwrap().success());
-        assert_eq!(out, "foobar\n".to_string());
+        assert_eq!(out, "foobar\n");
     }
 
     #[cfg(not(target_os="android"))]
@@ -900,7 +904,7 @@ fn test_process_output_output() {
         let output_str = str::from_utf8(output.as_slice()).unwrap();
 
         assert!(status.success());
-        assert_eq!(output_str.trim().to_string(), "hello".to_string());
+        assert_eq!(output_str.trim().to_string(), "hello");
         // FIXME #7224
         if !running_on_valgrind() {
             assert_eq!(error, Vec::new());
@@ -941,7 +945,7 @@ fn test_wait_with_output_once() {
         let output_str = str::from_utf8(output.as_slice()).unwrap();
 
         assert!(status.success());
-        assert_eq!(output_str.trim().to_string(), "hello".to_string());
+        assert_eq!(output_str.trim().to_string(), "hello");
         // FIXME #7224
         if !running_on_valgrind() {
             assert_eq!(error, Vec::new());
@@ -973,7 +977,7 @@ fn test_keep_current_working_dir() {
 
         let output = String::from_utf8(prog.wait_with_output().unwrap().output).unwrap();
         let parent_dir = os::getcwd().unwrap();
-        let child_dir = Path::new(output.as_slice().trim());
+        let child_dir = Path::new(output.trim());
 
         let parent_stat = parent_dir.stat().unwrap();
         let child_stat = child_dir.stat().unwrap();
@@ -991,7 +995,7 @@ fn test_change_working_directory() {
         let prog = pwd_cmd().cwd(&parent_dir).spawn().unwrap();
 
         let output = String::from_utf8(prog.wait_with_output().unwrap().output).unwrap();
-        let child_dir = Path::new(output.as_slice().trim());
+        let child_dir = Path::new(output.trim());
 
         let parent_stat = parent_dir.stat().unwrap();
         let child_stat = child_dir.stat().unwrap();
@@ -1031,8 +1035,7 @@ fn test_inherit_env() {
         for &(ref k, ref v) in r.iter() {
             // don't check windows magical empty-named variables
             assert!(k.is_empty() ||
-                    output.as_slice()
-                          .contains(format!("{}={}", *k, *v).as_slice()),
+                    output.contains(format!("{}={}", *k, *v).as_slice()),
                     "output doesn't contain `{}={}`\n{}",
                     k, v, output);
         }
@@ -1050,12 +1053,10 @@ fn test_inherit_env() {
         for &(ref k, ref v) in r.iter() {
             // don't check android RANDOM variables
             if *k != "RANDOM".to_string() {
-                assert!(output.as_slice()
-                              .contains(format!("{}={}",
+                assert!(output.contains(format!("{}={}",
                                                 *k,
                                                 *v).as_slice()) ||
-                        output.as_slice()
-                              .contains(format!("{}=\'{}\'",
+                        output.contains(format!("{}=\'{}\'",
                                                 *k,
                                                 *v).as_slice()));
             }
@@ -1084,7 +1085,7 @@ fn test_override_env() {
         let result = prog.wait_with_output().unwrap();
         let output = String::from_utf8_lossy(result.output.as_slice()).into_string();
 
-        assert!(output.as_slice().contains("RUN_TEST_NEW_ENV=123"),
+        assert!(output.contains("RUN_TEST_NEW_ENV=123"),
                 "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}", output);
     }
 
@@ -1094,7 +1095,7 @@ fn test_add_to_env() {
         let result = prog.wait_with_output().unwrap();
         let output = String::from_utf8_lossy(result.output.as_slice()).into_string();
 
-        assert!(output.as_slice().contains("RUN_TEST_NEW_ENV=123"),
+        assert!(output.contains("RUN_TEST_NEW_ENV=123"),
                 "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}", output);
     }
 
index cf2df0da7fe7b05befb242baa4024bc8d5b583ae..48c333f0733a5f038e97972b073b74134159f72a 100644 (file)
@@ -528,7 +528,7 @@ fn capture_stdout() {
             set_stdout(box w);
             println!("hello!");
         });
-        assert_eq!(r.read_to_string().unwrap(), "hello!\n".to_string());
+        assert_eq!(r.read_to_string().unwrap(), "hello!\n");
     }
 
     #[test]
@@ -543,6 +543,6 @@ fn capture_stderr() {
             panic!("my special message");
         });
         let s = r.read_to_string().unwrap();
-        assert!(s.as_slice().contains("my special message"));
+        assert!(s.contains("my special message"));
     }
 }
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 b42286c0308cede0f87260c7374abaa8eae8139a..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);
 
@@ -428,28 +441,28 @@ mod tests {
     #[test]
     fn test_int_to_str_overflow() {
         let mut i8_val: i8 = 127_i8;
-        assert_eq!(i8_val.to_string(), "127".to_string());
+        assert_eq!(i8_val.to_string(), "127");
 
         i8_val += 1 as i8;
-        assert_eq!(i8_val.to_string(), "-128".to_string());
+        assert_eq!(i8_val.to_string(), "-128");
 
         let mut i16_val: i16 = 32_767_i16;
-        assert_eq!(i16_val.to_string(), "32767".to_string());
+        assert_eq!(i16_val.to_string(), "32767");
 
         i16_val += 1 as i16;
-        assert_eq!(i16_val.to_string(), "-32768".to_string());
+        assert_eq!(i16_val.to_string(), "-32768");
 
         let mut i32_val: i32 = 2_147_483_647_i32;
-        assert_eq!(i32_val.to_string(), "2147483647".to_string());
+        assert_eq!(i32_val.to_string(), "2147483647");
 
         i32_val += 1 as i32;
-        assert_eq!(i32_val.to_string(), "-2147483648".to_string());
+        assert_eq!(i32_val.to_string(), "-2147483648");
 
         let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
-        assert_eq!(i64_val.to_string(), "9223372036854775807".to_string());
+        assert_eq!(i64_val.to_string(), "9223372036854775807");
 
         i64_val += 1 as i64;
-        assert_eq!(i64_val.to_string(), "-9223372036854775808".to_string());
+        assert_eq!(i64_val.to_string(), "-9223372036854775808");
     }
 }
 
index 7b79e53520140e6dbfaab7260a10308a71c0037c..0baefb11cf8f2a8ff593493a5760d5133a0b10a7 100644 (file)
@@ -79,28 +79,28 @@ pub fn test_parse_bytes() {
     #[test]
     fn test_uint_to_str_overflow() {
         let mut u8_val: u8 = 255_u8;
-        assert_eq!(u8_val.to_string(), "255".to_string());
+        assert_eq!(u8_val.to_string(), "255");
 
         u8_val += 1 as u8;
-        assert_eq!(u8_val.to_string(), "0".to_string());
+        assert_eq!(u8_val.to_string(), "0");
 
         let mut u16_val: u16 = 65_535_u16;
-        assert_eq!(u16_val.to_string(), "65535".to_string());
+        assert_eq!(u16_val.to_string(), "65535");
 
         u16_val += 1 as u16;
-        assert_eq!(u16_val.to_string(), "0".to_string());
+        assert_eq!(u16_val.to_string(), "0");
 
         let mut u32_val: u32 = 4_294_967_295_u32;
-        assert_eq!(u32_val.to_string(), "4294967295".to_string());
+        assert_eq!(u32_val.to_string(), "4294967295");
 
         u32_val += 1 as u32;
-        assert_eq!(u32_val.to_string(), "0".to_string());
+        assert_eq!(u32_val.to_string(), "0");
 
         let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
-        assert_eq!(u64_val.to_string(), "18446744073709551615".to_string());
+        assert_eq!(u64_val.to_string(), "18446744073709551615");
 
         u64_val += 1 as u64;
-        assert_eq!(u64_val.to_string(), "0".to_string());
+        assert_eq!(u64_val.to_string(), "0");
     }
 
     #[test]
index ba9bcc05546cd4d0786d981bd98fae03de0d1a9d..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;
@@ -316,7 +317,7 @@ unsafe fn get_env_pairs() -> Vec<Vec<u8>> {
         fn env_convert(input: Vec<Vec<u8>>) -> Vec<(Vec<u8>, Vec<u8>)> {
             let mut pairs = Vec::new();
             for p in input.iter() {
-                let mut it = p.as_slice().splitn(1, |b| *b == b'=');
+                let mut it = p.splitn(1, |b| *b == b'=');
                 let key = it.next().unwrap().to_vec();
                 let default: &[u8] = &[];
                 let val = it.next().unwrap_or(default).to_vec();
@@ -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]
@@ -2069,7 +2077,7 @@ fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
     #[cfg(unix)]
     fn join_paths_unix() {
         fn test_eq(input: &[&str], output: &str) -> bool {
-            join_paths(input).unwrap().as_slice() == output.as_bytes()
+            join_paths(input).unwrap() == output.as_bytes()
         }
 
         assert!(test_eq(&[], ""));
@@ -2084,7 +2092,7 @@ fn test_eq(input: &[&str], output: &str) -> bool {
     #[cfg(windows)]
     fn join_paths_windows() {
         fn test_eq(input: &[&str], output: &str) -> bool {
-            join_paths(input).unwrap().as_slice() == output.as_bytes()
+            join_paths(input).unwrap() == output.as_bytes()
         }
 
         assert!(test_eq(&[], ""));
index 01b42395471fc5ea6630dd92a9fba32add809f6f..c7feff8705e5fbabde993bc6c0cf359721445d11 100644 (file)
@@ -942,6 +942,6 @@ fn test_cstring() {
 
         let input = r"\foo\bar\baz";
         let path: WindowsPath = WindowsPath::new(input.to_c_str());
-        assert_eq!(path.as_str().unwrap(), input.as_slice());
+        assert_eq!(path.as_str().unwrap(), input);
     }
 }
index d6d27daf4ae8bd5770ca71ddffc5d55669a5060a..ba2c89bf1ce1a0c166a173ea799a214241a419e5 100644 (file)
@@ -132,7 +132,7 @@ unsafe fn new_unchecked<T: BytesContainer>(path: T) -> Path {
     unsafe fn set_filename_unchecked<T: BytesContainer>(&mut self, filename: T) {
         let filename = filename.container_as_bytes();
         match self.sepidx {
-            None if b".." == self.repr.as_slice() => {
+            None if b".." == self.repr => {
                 let mut v = Vec::with_capacity(3 + filename.len());
                 v.push_all(dot_dot_static);
                 v.push(SEP_BYTE);
@@ -159,7 +159,7 @@ unsafe fn set_filename_unchecked<T: BytesContainer>(&mut self, filename: T) {
                 self.repr = Path::normalize(v.as_slice());
             }
         }
-        self.sepidx = self.repr.as_slice().rposition_elem(&SEP_BYTE);
+        self.sepidx = self.repr.rposition_elem(&SEP_BYTE);
     }
 
     unsafe fn push_unchecked<T: BytesContainer>(&mut self, path: T) {
@@ -175,7 +175,7 @@ unsafe fn push_unchecked<T: BytesContainer>(&mut self, path: T) {
                 // FIXME: this is slow
                 self.repr = Path::normalize(v.as_slice());
             }
-            self.sepidx = self.repr.as_slice().rposition_elem(&SEP_BYTE);
+            self.sepidx = self.repr.rposition_elem(&SEP_BYTE);
         }
     }
 }
@@ -192,7 +192,7 @@ fn into_vec(self) -> Vec<u8> {
 
     fn dirname<'a>(&'a self) -> &'a [u8] {
         match self.sepidx {
-            None if b".." == self.repr.as_slice() => self.repr.as_slice(),
+            None if b".." == self.repr => self.repr.as_slice(),
             None => dot_static,
             Some(0) => self.repr[..1],
             Some(idx) if self.repr[idx+1..] == b".." => self.repr.as_slice(),
@@ -202,8 +202,8 @@ fn dirname<'a>(&'a self) -> &'a [u8] {
 
     fn filename<'a>(&'a self) -> Option<&'a [u8]> {
         match self.sepidx {
-            None if b"." == self.repr.as_slice() ||
-                b".." == self.repr.as_slice() => None,
+            None if b"." == self.repr ||
+                b".." == self.repr => None,
             None => Some(self.repr.as_slice()),
             Some(idx) if self.repr[idx+1..] == b".." => None,
             Some(0) if self.repr[1..].is_empty() => None,
@@ -213,20 +213,20 @@ fn filename<'a>(&'a self) -> Option<&'a [u8]> {
 
     fn pop(&mut self) -> bool {
         match self.sepidx {
-            None if b"." == self.repr.as_slice() => false,
+            None if b"." == self.repr => false,
             None => {
                 self.repr = vec![b'.'];
                 self.sepidx = None;
                 true
             }
-            Some(0) if b"/" == self.repr.as_slice() => false,
+            Some(0) if b"/" == self.repr => false,
             Some(idx) => {
                 if idx == 0 {
                     self.repr.truncate(idx+1);
                 } else {
                     self.repr.truncate(idx);
                 }
-                self.sepidx = self.repr.as_slice().rposition_elem(&SEP_BYTE);
+                self.sepidx = self.repr.rposition_elem(&SEP_BYTE);
                 true
             }
         }
@@ -251,7 +251,7 @@ fn is_ancestor_of(&self, other: &Path) -> bool {
         } else {
             let mut ita = self.components();
             let mut itb = other.components();
-            if b"." == self.repr.as_slice() {
+            if b"." == self.repr {
                 return match itb.next() {
                     None => true,
                     Some(b) => b != b".."
@@ -306,7 +306,7 @@ fn path_relative_from(&self, base: &Path) -> Option<Path> {
                     }
                 }
             }
-            Some(Path::new(comps.as_slice().connect_vec(&SEP_BYTE)))
+            Some(Path::new(comps.connect_vec(&SEP_BYTE)))
         }
     }
 
@@ -407,7 +407,7 @@ pub fn str_components<'a>(&'a self) -> StrComponents<'a> {
 
 // None result means the byte vector didn't need normalizing
 fn normalize_helper<'a>(v: &'a [u8], is_abs: bool) -> Option<Vec<&'a [u8]>> {
-    if is_abs && v.as_slice().is_empty() {
+    if is_abs && v.is_empty() {
         return None;
     }
     let mut comps: Vec<&'a [u8]> = vec![];
@@ -496,8 +496,8 @@ fn test_paths() {
         t!(s: Path::new("foo/../../.."), "../..");
         t!(s: Path::new("foo/../../bar"), "../bar");
 
-        assert_eq!(Path::new(b"foo/bar").into_vec().as_slice(), b"foo/bar");
-        assert_eq!(Path::new(b"/foo/../../bar").into_vec().as_slice(),
+        assert_eq!(Path::new(b"foo/bar").into_vec(), b"foo/bar");
+        assert_eq!(Path::new(b"/foo/../../bar").into_vec(),
                    b"/bar");
 
         let p = Path::new(b"foo/bar\x80");
@@ -537,7 +537,7 @@ macro_rules! t(
             ($path:expr, $disp:ident, $exp:expr) => (
                 {
                     let path = Path::new($path);
-                    assert!(path.$disp().to_string().as_slice() == $exp);
+                    assert!(path.$disp().to_string() == $exp);
                 }
             )
         )
@@ -580,9 +580,9 @@ macro_rules! t(
                 {
                     let path = Path::new($path);
                     let f = format!("{}", path.display());
-                    assert!(f.as_slice() == $exp);
+                    assert!(f == $exp);
                     let f = format!("{}", path.filename_display());
-                    assert!(f.as_slice() == $expf);
+                    assert!(f == $expf);
                 }
             )
         )
@@ -1180,7 +1180,7 @@ macro_rules! t(
                     let path = Path::new($arg);
                     let comps = path.components().collect::<Vec<&[u8]>>();
                     let exp: &[&[u8]] = &[$($exp),*];
-                    assert_eq!(comps.as_slice(), exp);
+                    assert_eq!(comps, exp);
                     let comps = path.components().rev().collect::<Vec<&[u8]>>();
                     let exp = exp.iter().rev().map(|&x|x).collect::<Vec<&[u8]>>();
                     assert_eq!(comps, exp)
@@ -1212,7 +1212,7 @@ macro_rules! t(
                     let path = Path::new($arg);
                     let comps = path.str_components().collect::<Vec<Option<&str>>>();
                     let exp: &[Option<&str>] = &$exp;
-                    assert_eq!(comps.as_slice(), exp);
+                    assert_eq!(comps, exp);
                     let comps = path.str_components().rev().collect::<Vec<Option<&str>>>();
                     let exp = exp.iter().rev().map(|&x|x).collect::<Vec<Option<&str>>>();
                     assert_eq!(comps, exp);
index 08e318d32b9fc8ca42ce7b661b99381c0c33c26a..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};
@@ -182,7 +183,7 @@ unsafe fn new_unchecked<T: BytesContainer>(path: T) -> Path {
     unsafe fn set_filename_unchecked<T: BytesContainer>(&mut self, filename: T) {
         let filename = filename.container_as_str().unwrap();
         match self.sepidx_or_prefix_len() {
-            None if ".." == self.repr.as_slice() => {
+            None if ".." == self.repr => {
                 let mut s = String::with_capacity(3 + filename.len());
                 s.push_str("..");
                 s.push(SEP);
@@ -192,22 +193,22 @@ unsafe fn set_filename_unchecked<T: BytesContainer>(&mut self, filename: T) {
             None => {
                 self.update_normalized(filename);
             }
-            Some((_,idxa,end)) if self.repr.as_slice().slice(idxa,end) == ".." => {
+            Some((_,idxa,end)) if self.repr.slice(idxa,end) == ".." => {
                 let mut s = String::with_capacity(end + 1 + filename.len());
-                s.push_str(self.repr.as_slice().slice_to(end));
+                s.push_str(self.repr.slice_to(end));
                 s.push(SEP);
                 s.push_str(filename);
                 self.update_normalized(s);
             }
             Some((idxb,idxa,_)) if self.prefix == Some(DiskPrefix) && idxa == self.prefix_len() => {
                 let mut s = String::with_capacity(idxb + filename.len());
-                s.push_str(self.repr.as_slice().slice_to(idxb));
+                s.push_str(self.repr.slice_to(idxb));
                 s.push_str(filename);
                 self.update_normalized(s);
             }
             Some((idxb,_,_)) => {
                 let mut s = String::with_capacity(idxb + 1 + filename.len());
-                s.push_str(self.repr.as_slice().slice_to(idxb));
+                s.push_str(self.repr.slice_to(idxb));
                 s.push(SEP);
                 s.push_str(filename);
                 self.update_normalized(s);
@@ -356,21 +357,21 @@ fn dirname<'a>(&'a self) -> &'a [u8] {
     /// Always returns a `Some` value.
     fn dirname_str<'a>(&'a self) -> Option<&'a str> {
         Some(match self.sepidx_or_prefix_len() {
-            None if ".." == self.repr.as_slice() => self.repr.as_slice(),
+            None if ".." == self.repr => self.repr.as_slice(),
             None => ".",
-            Some((_,idxa,end)) if self.repr.as_slice().slice(idxa, end) == ".." => {
+            Some((_,idxa,end)) if self.repr.slice(idxa, end) == ".." => {
                 self.repr.as_slice()
             }
-            Some((idxb,_,end)) if self.repr.as_slice().slice(idxb, end) == "\\" => {
+            Some((idxb,_,end)) if self.repr.slice(idxb, end) == "\\" => {
                 self.repr.as_slice()
             }
-            Some((0,idxa,_)) => self.repr.as_slice().slice_to(idxa),
+            Some((0,idxa,_)) => self.repr.slice_to(idxa),
             Some((idxb,idxa,_)) => {
                 match self.prefix {
                     Some(DiskPrefix) | Some(VerbatimDiskPrefix) if idxb == self.prefix_len() => {
-                        self.repr.as_slice().slice_to(idxa)
+                        self.repr.slice_to(idxa)
                     }
-                    _ => self.repr.as_slice().slice_to(idxb)
+                    _ => self.repr.slice_to(idxb)
                 }
             }
         })
@@ -415,14 +416,14 @@ fn dir_path(&self) -> Path {
     #[inline]
     fn pop(&mut self) -> bool {
         match self.sepidx_or_prefix_len() {
-            None if "." == self.repr.as_slice() => false,
+            None if "." == self.repr => false,
             None => {
                 self.repr = String::from_str(".");
                 self.sepidx = None;
                 true
             }
             Some((idxb,idxa,end)) if idxb == idxa && idxb == end => false,
-            Some((idxb,_,end)) if self.repr.as_slice().slice(idxb, end) == "\\" => false,
+            Some((idxb,_,end)) if self.repr.slice(idxb, end) == "\\" => false,
             Some((idxb,idxa,_)) => {
                 let trunc = match self.prefix {
                     Some(DiskPrefix) | Some(VerbatimDiskPrefix) | None => {
@@ -442,15 +443,15 @@ fn root_path(&self) -> Option<Path> {
         if self.prefix.is_some() {
             Some(Path::new(match self.prefix {
                 Some(DiskPrefix) if self.is_absolute() => {
-                    self.repr.as_slice().slice_to(self.prefix_len()+1)
+                    self.repr.slice_to(self.prefix_len()+1)
                 }
                 Some(VerbatimDiskPrefix) => {
-                    self.repr.as_slice().slice_to(self.prefix_len()+1)
+                    self.repr.slice_to(self.prefix_len()+1)
                 }
-                _ => self.repr.as_slice().slice_to(self.prefix_len())
+                _ => self.repr.slice_to(self.prefix_len())
             }))
         } else if is_vol_relative(self) {
-            Some(Path::new(self.repr.as_slice().slice_to(1)))
+            Some(Path::new(self.repr.slice_to(1)))
         } else {
             None
         }
@@ -469,7 +470,7 @@ fn root_path(&self) -> Option<Path> {
     fn is_absolute(&self) -> bool {
         match self.prefix {
             Some(DiskPrefix) => {
-                let rest = self.repr.as_slice().slice_from(self.prefix_len());
+                let rest = self.repr.slice_from(self.prefix_len());
                 rest.len() > 0 && rest.as_bytes()[0] == SEP_BYTE
             }
             Some(_) => true,
@@ -491,7 +492,7 @@ fn is_ancestor_of(&self, other: &Path) -> bool {
         } else {
             let mut ita = self.str_components().map(|x|x.unwrap());
             let mut itb = other.str_components().map(|x|x.unwrap());
-            if "." == self.repr.as_slice() {
+            if "." == self.repr {
                 return itb.next() != Some("..");
             }
             loop {
@@ -827,7 +828,7 @@ fn normalize__(s: &str, prefix: Option<PathPrefix>) -> Option<String> {
 
     fn update_sepidx(&mut self) {
         let s = if self.has_nonsemantic_trailing_slash() {
-                    self.repr.as_slice().slice_to(self.repr.len()-1)
+                    self.repr.slice_to(self.repr.len()-1)
                 } else { self.repr.as_slice() };
         let idx = s.rfind(if !prefix_is_verbatim(self.prefix) { is_sep }
                           else { is_sep_verbatim });
@@ -923,7 +924,7 @@ pub fn make_non_verbatim(path: &Path) -> Option<Path> {
     }
     // now ensure normalization didn't change anything
     if repr.slice_from(path.prefix_len()) ==
-        new_path.repr.as_slice().slice_from(new_path.prefix_len()) {
+        new_path.repr.slice_from(new_path.prefix_len()) {
         Some(new_path)
     } else {
         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("\\\\") {
         // \\
@@ -1233,8 +1236,8 @@ fn test_paths() {
         t!(s: Path::new("foo\\..\\..\\.."), "..\\..");
         t!(s: Path::new("foo\\..\\..\\bar"), "..\\bar");
 
-        assert_eq!(Path::new(b"foo\\bar").into_vec().as_slice(), b"foo\\bar");
-        assert_eq!(Path::new(b"\\foo\\..\\..\\bar").into_vec().as_slice(), b"\\bar");
+        assert_eq!(Path::new(b"foo\\bar").into_vec(), b"foo\\bar");
+        assert_eq!(Path::new(b"\\foo\\..\\..\\bar").into_vec(), b"\\bar");
 
         t!(s: Path::new("\\\\a"), "\\a");
         t!(s: Path::new("\\\\a\\"), "\\a");
@@ -1322,9 +1325,9 @@ fn test_not_utf8_panics() {
     #[test]
     fn test_display_str() {
         let path = Path::new("foo");
-        assert_eq!(path.display().to_string(), "foo".to_string());
+        assert_eq!(path.display().to_string(), "foo");
         let path = Path::new(b"\\");
-        assert_eq!(path.filename_display().to_string(), "".to_string());
+        assert_eq!(path.filename_display().to_string(), "");
 
         let path = Path::new("foo");
         let mo = path.display().as_cow();
@@ -1341,9 +1344,9 @@ macro_rules! t(
                 {
                     let path = Path::new($path);
                     let f = format!("{}", path.display());
-                    assert_eq!(f.as_slice(), $exp);
+                    assert_eq!(f, $exp);
                     let f = format!("{}", path.filename_display());
-                    assert_eq!(f.as_slice(), $expf);
+                    assert_eq!(f, $expf);
                 }
             )
         )
@@ -2246,7 +2249,7 @@ macro_rules! t(
                     let comps = path.str_components().map(|x|x.unwrap())
                                 .collect::<Vec<&str>>();
                     let exp: &[&str] = &$exp;
-                    assert_eq!(comps.as_slice(), exp);
+                    assert_eq!(comps, exp);
                     let comps = path.str_components().rev().map(|x|x.unwrap())
                                 .collect::<Vec<&str>>();
                     let exp = exp.iter().rev().map(|&x|x).collect::<Vec<&str>>();
@@ -2303,7 +2306,7 @@ macro_rules! t(
                     let path = Path::new($path);
                     let comps = path.components().collect::<Vec<&[u8]>>();
                     let exp: &[&[u8]] = &$exp;
-                    assert_eq!(comps.as_slice(), exp);
+                    assert_eq!(comps, exp);
                     let comps = path.components().rev().collect::<Vec<&[u8]>>();
                     let exp = exp.iter().rev().map(|&x|x).collect::<Vec<&[u8]>>();
                     assert_eq!(comps, exp);
index 413d9267152ebdcc07323c3e654a2a20145c800d..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`.
@@ -529,7 +534,7 @@ fn test_shuffle() {
         let mut one = [1i];
         r.shuffle(&mut one);
         let b: &[_] = &[1];
-        assert_eq!(one.as_slice(), b);
+        assert_eq!(one, b);
 
         let mut two = [1i, 2];
         r.shuffle(&mut two);
@@ -538,7 +543,7 @@ fn test_shuffle() {
         let mut x = [1i, 1, 1];
         r.shuffle(&mut x);
         let b: &[_] = &[1, 1, 1];
-        assert_eq!(x.as_slice(), b);
+        assert_eq!(x, b);
     }
 
     #[test]
@@ -548,7 +553,7 @@ fn test_task_rng() {
         let mut v = [1i, 1, 1];
         r.shuffle(&mut v);
         let b: &[_] = &[1, 1, 1];
-        assert_eq!(v.as_slice(), b);
+        assert_eq!(v, b);
         assert_eq!(r.gen_range(0u, 1u), 0u);
     }
 
index 3698a91855cd621fcf664ec0386eaa7956f159c6..4ac09a071bbee0f321b272f4d5194d4a04742d07 100644 (file)
@@ -1013,7 +1013,7 @@ mod test {
     macro_rules! t( ($a:expr, $b:expr) => ({
         let mut m = Vec::new();
         super::demangle(&mut m, $a).unwrap();
-        assert_eq!(String::from_utf8(m).unwrap(), $b.to_string());
+        assert_eq!(String::from_utf8(m).unwrap(), $b);
     }) )
 
     #[test]
index 79e0d487cadb9b3996ba8c739a1c671015ed384f..a8c9983e5aac56e30c9f0e369d6968c76549a625 100644 (file)
@@ -153,7 +153,7 @@ mod test {
     #[test]
     fn test_from_value() {
         let mut f = Future::from_value("snail".to_string());
-        assert_eq!(f.get(), "snail".to_string());
+        assert_eq!(f.get(), "snail");
     }
 
     #[test]
@@ -161,25 +161,25 @@ fn test_from_receiver() {
         let (tx, rx) = channel();
         tx.send("whale".to_string());
         let mut f = Future::from_receiver(rx);
-        assert_eq!(f.get(), "whale".to_string());
+        assert_eq!(f.get(), "whale");
     }
 
     #[test]
     fn test_from_fn() {
         let mut f = Future::from_fn(proc() "brail".to_string());
-        assert_eq!(f.get(), "brail".to_string());
+        assert_eq!(f.get(), "brail");
     }
 
     #[test]
     fn test_interface_get() {
         let mut f = Future::from_value("fail".to_string());
-        assert_eq!(f.get(), "fail".to_string());
+        assert_eq!(f.get(), "fail");
     }
 
     #[test]
     fn test_interface_unwrap() {
         let f = Future::from_value("fail".to_string());
-        assert_eq!(f.unwrap(), "fail".to_string());
+        assert_eq!(f.unwrap(), "fail");
     }
 
     #[test]
@@ -191,7 +191,7 @@ fn test_get_ref_method() {
     #[test]
     fn test_spawn() {
         let mut f = Future::spawn(proc() "bale".to_string());
-        assert_eq!(f.get(), "bale".to_string());
+        assert_eq!(f.get(), "bale");
     }
 
     #[test]
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 a773ef7e31747c9c1623ee4657de672b4e48616b..66f7d85f20dfb4e15cc2cdc2ba3f939ed77effae 100644 (file)
@@ -201,7 +201,7 @@ fn prune(root: &CString, dirs: Vec<Path>) -> Vec<Path> {
 
     let size = unsafe { rust_dirent_t_size() };
     let mut buf = Vec::<u8>::with_capacity(size as uint);
-    let ptr = buf.as_mut_slice().as_mut_ptr() as *mut dirent_t;
+    let ptr = buf.as_mut_ptr() as *mut dirent_t;
 
     let p = p.to_c_str();
     let dir_ptr = unsafe {opendir(p.as_ptr())};
index 9402c63dcf558b6a3c001a28297d40c7edc76596..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;
@@ -376,8 +376,8 @@ pub fn readlink(p: &Path) -> IoResult<Path> {
                                   libc::VOLUME_NAME_DOS)
     });
     let ret = match ret {
-        Some(ref s) if s.as_slice().starts_with(r"\\?\") => { // "
-            Ok(Path::new(s.as_slice().slice_from(4)))
+        Some(ref s) if s.starts_with(r"\\?\") => { // "
+            Ok(Path::new(s.slice_from(4)))
         }
         Some(s) => Ok(Path::new(s)),
         None => Err(super::last_error()),
index 78a8e09dac1a002a14f1945d1ef2792150c50778..02548bedf028be1b4c4829d73d1c5828c0eb2b9f 100644 (file)
@@ -223,7 +223,7 @@ pub fn spawn<K, V, C, P>(cfg: &C, in_fd: Option<P>,
 
             with_envp(cfg.env(), |envp| {
                 with_dirp(cfg.cwd(), |dirp| {
-                    let mut cmd_str: Vec<u16> = cmd_str.as_slice().utf16_units().collect();
+                    let mut cmd_str: Vec<u16> = cmd_str.utf16_units().collect();
                     cmd_str.push(0);
                     let created = CreateProcessW(ptr::null(),
                                                  cmd_str.as_mut_ptr(),
@@ -433,7 +433,7 @@ fn with_envp<K, V, T>(env: Option<&collections::HashMap<K, V>>,
                 let kv = format!("{}={}",
                                  pair.ref0().container_as_str().unwrap(),
                                  pair.ref1().container_as_str().unwrap());
-                blk.extend(kv.as_slice().utf16_units());
+                blk.extend(kv.utf16_units());
                 blk.push(0);
             }
 
@@ -484,24 +484,24 @@ fn test_wrapper(prog: &str, args: &[&str]) -> String {
 
         assert_eq!(
             test_wrapper("prog", &["aaa", "bbb", "ccc"]),
-            "prog aaa bbb ccc".to_string()
+            "prog aaa bbb ccc"
         );
 
         assert_eq!(
             test_wrapper("C:\\Program Files\\blah\\blah.exe", &["aaa"]),
-            "\"C:\\Program Files\\blah\\blah.exe\" aaa".to_string()
+            "\"C:\\Program Files\\blah\\blah.exe\" aaa"
         );
         assert_eq!(
             test_wrapper("C:\\Program Files\\test", &["aa\"bb"]),
-            "\"C:\\Program Files\\test\" aa\\\"bb".to_string()
+            "\"C:\\Program Files\\test\" aa\\\"bb"
         );
         assert_eq!(
             test_wrapper("echo", &["a b c"]),
-            "echo \"a b c\"".to_string()
+            "echo \"a b c\""
         );
         assert_eq!(
             test_wrapper("\u03c0\u042f\u97f3\u00e6\u221e", &[]),
-            "\u03c0\u042f\u97f3\u00e6\u221e".to_string()
+            "\u03c0\u042f\u97f3\u00e6\u221e"
         );
     }
 }
index 0e7b06cbb94785822c7d652038e880930f22174c..51679bb2003fc8e3a42b27b0a536e62ff3d4dae9 100644 (file)
@@ -113,7 +113,7 @@ pub fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
     pub fn write(&mut self, buf: &[u8]) -> IoResult<()> {
         let utf16 = match from_utf8(buf) {
             Some(utf8) => {
-                utf8.as_slice().utf16_units().collect::<Vec<u16>>()
+                utf8.utf16_units().collect::<Vec<u16>>()
             }
             None => return Err(invalid_encoding()),
         };
index 8b4dbf61c181d448291b0f2bfb30c88cfa375b3f..c91417e611ed1165fe6a574d37ea24b943dcdd7c 100644 (file)
@@ -55,7 +55,7 @@
 use rustrt::local::Local;
 use rustrt::task::Task;
 use rustrt::task;
-use str::{Str, SendStr};
+use str::SendStr;
 use string::{String, ToString};
 use sync::Future;
 
@@ -244,7 +244,7 @@ pub fn name() -> Option<String> {
 
     let task = Local::borrow(None::<Task>);
     match task.name {
-        Some(ref name) => Some(name.as_slice().to_string()),
+        Some(ref name) => Some(name.to_string()),
         None => None
     }
 }
@@ -289,21 +289,21 @@ fn test_unnamed_task() {
     #[test]
     fn test_owned_named_task() {
         TaskBuilder::new().named("ada lovelace".to_string()).try(proc() {
-            assert!(name().unwrap() == "ada lovelace".to_string());
+            assert!(name().unwrap() == "ada lovelace");
         }).map_err(|_| ()).unwrap();
     }
 
     #[test]
     fn test_static_named_task() {
         TaskBuilder::new().named("ada lovelace").try(proc() {
-            assert!(name().unwrap() == "ada lovelace".to_string());
+            assert!(name().unwrap() == "ada lovelace");
         }).map_err(|_| ()).unwrap();
     }
 
     #[test]
     fn test_send_named_task() {
         TaskBuilder::new().named("ada lovelace".into_cow()).try(proc() {
-            assert!(name().unwrap() == "ada lovelace".to_string());
+            assert!(name().unwrap() == "ada lovelace");
         }).map_err(|_| ()).unwrap();
     }
 
@@ -464,7 +464,7 @@ fn test_try_panic_message_owned_str() {
             Err(e) => {
                 type T = String;
                 assert!(e.is::<T>());
-                assert_eq!(*e.downcast::<T>().unwrap(), "owned string".to_string());
+                assert_eq!(*e.downcast::<T>().unwrap(), "owned string");
             }
             Ok(()) => panic!()
         }
@@ -511,7 +511,7 @@ fn test_stdout() {
         assert!(r.is_ok());
 
         let output = reader.read_to_string().unwrap();
-        assert_eq!(output, "Hello, world!".to_string());
+        assert_eq!(output, "Hello, world!");
     }
 
     // NOTE: the corresponding test for stderr is in run-pass/task-stderr, due
index 63eb9a9873624a4d580e0bdc01a06b0ea7f62564..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.
@@ -540,20 +543,20 @@ fn test_duration_div() {
 
     #[test]
     fn test_duration_fmt() {
-        assert_eq!(Duration::zero().to_string(), "PT0S".to_string());
-        assert_eq!(Duration::days(42).to_string(), "P42D".to_string());
-        assert_eq!(Duration::days(-42).to_string(), "-P42D".to_string());
-        assert_eq!(Duration::seconds(42).to_string(), "PT42S".to_string());
-        assert_eq!(Duration::milliseconds(42).to_string(), "PT0.042S".to_string());
-        assert_eq!(Duration::microseconds(42).to_string(), "PT0.000042S".to_string());
-        assert_eq!(Duration::nanoseconds(42).to_string(), "PT0.000000042S".to_string());
+        assert_eq!(Duration::zero().to_string(), "PT0S");
+        assert_eq!(Duration::days(42).to_string(), "P42D");
+        assert_eq!(Duration::days(-42).to_string(), "-P42D");
+        assert_eq!(Duration::seconds(42).to_string(), "PT42S");
+        assert_eq!(Duration::milliseconds(42).to_string(), "PT0.042S");
+        assert_eq!(Duration::microseconds(42).to_string(), "PT0.000042S");
+        assert_eq!(Duration::nanoseconds(42).to_string(), "PT0.000000042S");
         assert_eq!((Duration::days(7) + Duration::milliseconds(6543)).to_string(),
-                   "P7DT6.543S".to_string());
-        assert_eq!(Duration::seconds(-86401).to_string(), "-P1DT1S".to_string());
-        assert_eq!(Duration::nanoseconds(-1).to_string(), "-PT0.000000001S".to_string());
+                   "P7DT6.543S");
+        assert_eq!(Duration::seconds(-86401).to_string(), "-P1DT1S");
+        assert_eq!(Duration::nanoseconds(-1).to_string(), "-PT0.000000001S");
 
         // the format specifier should have no effect on `Duration`
         assert_eq!(format!("{:30}", Duration::days(1) + Duration::milliseconds(2345)),
-                   "P1DT2.345S".to_string());
+                   "P1DT2.345S");
     }
 }
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 2913666a31535b7aebd99a0af543272bdb5b164a..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
@@ -260,7 +266,7 @@ fn entry_count(&self) -> uint {
     }
 
     fn find_entry(&self, id: NodeId) -> Option<MapEntry<'ast>> {
-        self.map.borrow().as_slice().get(id as uint).map(|e| *e)
+        self.map.borrow().get(id as uint).map(|e| *e)
     }
 
     pub fn krate(&self) -> &'ast Crate {
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 27e8c265e5c340ae9517c6e1e88d3db7db973579..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
@@ -290,7 +304,7 @@ pub fn get_line(&self, line_number: uint) -> Option<String> {
         lines.get(line_number).map(|&line| {
             let begin: BytePos = line - self.start_pos;
             let begin = begin.to_uint();
-            let slice = self.src.as_slice().slice_from(begin);
+            let slice = self.src.slice_from(begin);
             match slice.find('\n') {
                 Some(e) => slice.slice_to(e),
                 None => slice
@@ -308,8 +322,8 @@ pub fn record_multibyte_char(&self, pos: BytePos, bytes: uint) {
     }
 
     pub fn is_real_file(&self) -> bool {
-        !(self.name.as_slice().starts_with("<") &&
-          self.name.as_slice().ends_with(">"))
+        !(self.name.starts_with("<") &&
+          self.name.ends_with(">"))
     }
 }
 
@@ -336,8 +350,8 @@ pub fn new_filemap(&self, filename: FileName, src: String) -> Rc<FileMap> {
         // Remove utf-8 BOM if any.
         // FIXME #12884: no efficient/safe way to remove from the start of a string
         // and reuse the allocation.
-        let mut src = if src.as_slice().starts_with("\ufeff") {
-            String::from_str(src.as_slice().slice_from(3))
+        let mut src = if src.starts_with("\ufeff") {
+            String::from_str(src.slice_from(3))
         } else {
             String::from_str(src.as_slice())
         };
@@ -346,7 +360,7 @@ pub fn new_filemap(&self, filename: FileName, src: String) -> Rc<FileMap> {
         // This is a workaround to prevent CodeMap.lookup_filemap_idx from accidentally
         // overflowing into the next filemap in case the last byte of span is also the last
         // byte of filemap, which leads to incorrect results from CodeMap.span_to_*.
-        if src.len() > 0 && !src.as_slice().ends_with("\n") {
+        if src.len() > 0 && !src.ends_with("\n") {
             src.push('\n');
         }
 
@@ -426,14 +440,14 @@ pub fn span_to_snippet(&self, sp: Span) -> Option<String> {
         if begin.fm.start_pos != end.fm.start_pos {
             None
         } else {
-            Some(begin.fm.src.as_slice().slice(begin.pos.to_uint(),
-                                               end.pos.to_uint()).to_string())
+            Some(begin.fm.src.slice(begin.pos.to_uint(),
+                                    end.pos.to_uint()).to_string())
         }
     }
 
     pub fn get_filemap(&self, filename: &str) -> Rc<FileMap> {
         for fm in self.files.borrow().iter() {
-            if filename == fm.name.as_slice() {
+            if filename == fm.name {
                 return fm.clone();
             }
         }
@@ -614,11 +628,11 @@ fn t3() {
         let cm = init_code_map();
 
         let fmabp1 = cm.lookup_byte_offset(BytePos(22));
-        assert_eq!(fmabp1.fm.name, "blork.rs".to_string());
+        assert_eq!(fmabp1.fm.name, "blork.rs");
         assert_eq!(fmabp1.pos, BytePos(22));
 
         let fmabp2 = cm.lookup_byte_offset(BytePos(24));
-        assert_eq!(fmabp2.fm.name, "blork2.rs".to_string());
+        assert_eq!(fmabp2.fm.name, "blork2.rs");
         assert_eq!(fmabp2.pos, BytePos(0));
     }
 
@@ -640,12 +654,12 @@ fn t5() {
         let cm = init_code_map();
 
         let loc1 = cm.lookup_char_pos(BytePos(22));
-        assert_eq!(loc1.file.name, "blork.rs".to_string());
+        assert_eq!(loc1.file.name, "blork.rs");
         assert_eq!(loc1.line, 2);
         assert_eq!(loc1.col, CharPos(10));
 
         let loc2 = cm.lookup_char_pos(BytePos(24));
-        assert_eq!(loc2.file.name, "blork2.rs".to_string());
+        assert_eq!(loc2.file.name, "blork2.rs");
         assert_eq!(loc2.line, 1);
         assert_eq!(loc2.col, CharPos(0));
     }
@@ -701,7 +715,7 @@ fn t7() {
         let span = Span {lo: BytePos(12), hi: BytePos(23), expn_id: NO_EXPANSION};
         let file_lines = cm.span_to_lines(span);
 
-        assert_eq!(file_lines.file.name, "blork.rs".to_string());
+        assert_eq!(file_lines.file.name, "blork.rs");
         assert_eq!(file_lines.lines.len(), 1);
         assert_eq!(file_lines.lines[0], 1u);
     }
@@ -723,6 +737,6 @@ fn t9() {
         let span = Span {lo: BytePos(12), hi: BytePos(23), expn_id: NO_EXPANSION};
         let sstr =  cm.span_to_string(span);
 
-        assert_eq!(sstr, "blork.rs:2:1: 2:12".to_string());
+        assert_eq!(sstr, "blork.rs:2:1: 2:12");
     }
 }
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 8d0d399fa31531a91693530166f2dabdf517c1df..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.
     ///
@@ -527,7 +529,7 @@ pub fn original_span_in_file(&self) -> Span {
         let mut call_site = None;
         loop {
             let expn_info = self.codemap().with_expn_info(expn_id, |ei| {
-                ei.map(|ei| (ei.call_site, ei.callee.name.as_slice() == "include"))
+                ei.map(|ei| (ei.call_site, ei.callee.name == "include"))
             });
             match expn_info {
                 None => break,
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 d7d6c636849a66a27fdae1ebeae2c77b9a266340..c8fed3dcd16f6f092bdee2ef7cf1adad042e2669 100644 (file)
@@ -577,17 +577,11 @@ fn to_expr(mut self, invocation: Invocation) -> P<ast::Expr> {
         }
 
         // Now create a vector containing all the arguments
-        let slicename = self.ecx.ident_of("__args_vec");
-        {
-            let args = names.into_iter().map(|a| a.unwrap());
-            let args = locals.into_iter().chain(args);
-            let args = self.ecx.expr_vec_slice(self.fmtsp, args.collect());
-            lets.push(self.ecx.stmt_let(self.fmtsp, false, slicename, args));
-        }
+        let args = locals.into_iter().chain(names.into_iter().map(|a| a.unwrap()));
 
         // Now create the fmt::Arguments struct with all our locals we created.
         let pieces = self.ecx.expr_ident(self.fmtsp, static_str_name);
-        let args_slice = self.ecx.expr_ident(self.fmtsp, slicename);
+        let args_slice = self.ecx.expr_vec_slice(self.fmtsp, args.collect());
 
         let (fn_name, fn_args) = if self.all_pieces_simple {
             ("new", vec![pieces, args_slice])
@@ -602,29 +596,18 @@ fn to_expr(mut self, invocation: Invocation) -> P<ast::Expr> {
                 self.ecx.ident_of("Arguments"),
                 self.ecx.ident_of(fn_name)), fn_args);
 
-        // We did all the work of making sure that the arguments
-        // structure is safe, so we can safely have an unsafe block.
-        let result = self.ecx.expr_block(P(ast::Block {
-           view_items: Vec::new(),
-           stmts: Vec::new(),
-           expr: Some(result),
-           id: ast::DUMMY_NODE_ID,
-           rules: ast::UnsafeBlock(ast::CompilerGenerated),
-           span: self.fmtsp,
-        }));
-        let resname = self.ecx.ident_of("__args");
-        lets.push(self.ecx.stmt_let(self.fmtsp, false, resname, result));
-        let res = self.ecx.expr_ident(self.fmtsp, resname);
         let result = match invocation {
             Call(e) => {
                 let span = e.span;
-                self.ecx.expr_call(span, e,
-                                   vec!(self.ecx.expr_addr_of(span, res)))
+                self.ecx.expr_call(span, e, vec![
+                    self.ecx.expr_addr_of(span, result)
+                ])
             }
             MethodCall(e, m) => {
                 let span = e.span;
-                self.ecx.expr_method_call(span, e, m,
-                                          vec!(self.ecx.expr_addr_of(span, res)))
+                self.ecx.expr_method_call(span, e, m, vec![
+                    self.ecx.expr_addr_of(span, result)
+                ])
             }
         };
         let body = self.ecx.expr_block(self.ecx.block(self.fmtsp, lets,
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 11c65d531f6fd07f39625d657ab8273b299ff76f..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,
         }
     }
 }
@@ -132,7 +139,7 @@ fn gate_feature(&self, feature: &str, span: Span, explain: &str) {
     }
 
     fn has_feature(&self, feature: &str) -> bool {
-        self.features.iter().any(|n| n.as_slice() == feature)
+        self.features.iter().any(|&n| n == feature)
     }
 }
 
@@ -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 b62d2d744c9e02b96bffad124bd8fa05ffa61df6..a17d66476c08c632b38d6d3ce72cae597b1c03f8 100644 (file)
@@ -36,6 +36,8 @@ pub enum CommentStyle {
     BlankLine,
 }
 
+impl Copy for CommentStyle {}
+
 #[deriving(Clone)]
 pub struct Comment {
     pub style: CommentStyle,
@@ -66,21 +68,20 @@ fn vertical_trim(lines: Vec<String> ) -> Vec<String> {
         let mut j = lines.len();
         // first line of all-stars should be omitted
         if lines.len() > 0 &&
-                lines[0].as_slice().chars().all(|c| c == '*') {
+                lines[0].chars().all(|c| c == '*') {
             i += 1;
         }
-        while i < j && lines[i].as_slice().trim().is_empty() {
+        while i < j && lines[i].trim().is_empty() {
             i += 1;
         }
         // like the first, a last line of all stars should be omitted
         if j > i && lines[j - 1]
-                         .as_slice()
                          .chars()
                          .skip(1)
                          .all(|c| c == '*') {
             j -= 1;
         }
-        while j > i && lines[j - 1].as_slice().trim().is_empty() {
+        while j > i && lines[j - 1].trim().is_empty() {
             j -= 1;
         }
         return lines.slice(i, j).iter().map(|x| (*x).clone()).collect();
@@ -92,7 +93,7 @@ fn horizontal_trim(lines: Vec<String> ) -> Vec<String> {
         let mut can_trim = true;
         let mut first = true;
         for line in lines.iter() {
-            for (j, c) in line.as_slice().chars().enumerate() {
+            for (j, c) in line.chars().enumerate() {
                 if j > i || !"* \t".contains_char(c) {
                     can_trim = false;
                     break;
@@ -117,7 +118,7 @@ fn horizontal_trim(lines: Vec<String> ) -> Vec<String> {
 
         if can_trim {
             lines.iter().map(|line| {
-                line.as_slice().slice(i + 1, line.len()).to_string()
+                line.slice(i + 1, line.len()).to_string()
             }).collect()
         } else {
             lines
@@ -228,7 +229,7 @@ fn trim_whitespace_prefix_and_push_line(lines: &mut Vec<String> ,
     let s1 = match all_whitespace(s.as_slice(), col) {
         Some(col) => {
             if col < len {
-                s.as_slice().slice(col, len).to_string()
+                s.slice(col, len).to_string()
             } else {
                 "".to_string()
             }
@@ -265,7 +266,7 @@ fn read_block_comment(rdr: &mut StringReader,
         if is_block_doc_comment(curr_line.as_slice()) {
             return
         }
-        assert!(!curr_line.as_slice().contains_char('\n'));
+        assert!(!curr_line.contains_char('\n'));
         lines.push(curr_line);
     } else {
         let mut level: int = 1;
@@ -390,41 +391,41 @@ mod test {
     #[test] fn test_block_doc_comment_1() {
         let comment = "/**\n * Test \n **  Test\n *   Test\n*/";
         let stripped = strip_doc_comment_decoration(comment);
-        assert_eq!(stripped, " Test \n*  Test\n   Test".to_string());
+        assert_eq!(stripped, " Test \n*  Test\n   Test");
     }
 
     #[test] fn test_block_doc_comment_2() {
         let comment = "/**\n * Test\n *  Test\n*/";
         let stripped = strip_doc_comment_decoration(comment);
-        assert_eq!(stripped, " Test\n  Test".to_string());
+        assert_eq!(stripped, " Test\n  Test");
     }
 
     #[test] fn test_block_doc_comment_3() {
         let comment = "/**\n let a: *int;\n *a = 5;\n*/";
         let stripped = strip_doc_comment_decoration(comment);
-        assert_eq!(stripped, " let a: *int;\n *a = 5;".to_string());
+        assert_eq!(stripped, " let a: *int;\n *a = 5;");
     }
 
     #[test] fn test_block_doc_comment_4() {
         let comment = "/*******************\n test\n *********************/";
         let stripped = strip_doc_comment_decoration(comment);
-        assert_eq!(stripped, " test".to_string());
+        assert_eq!(stripped, " test");
     }
 
     #[test] fn test_line_doc_comment() {
         let stripped = strip_doc_comment_decoration("/// test");
-        assert_eq!(stripped, " test".to_string());
+        assert_eq!(stripped, " test");
         let stripped = strip_doc_comment_decoration("///! test");
-        assert_eq!(stripped, " test".to_string());
+        assert_eq!(stripped, " test");
         let stripped = strip_doc_comment_decoration("// test");
-        assert_eq!(stripped, " test".to_string());
+        assert_eq!(stripped, " test");
         let stripped = strip_doc_comment_decoration("// test");
-        assert_eq!(stripped, " test".to_string());
+        assert_eq!(stripped, " test");
         let stripped = strip_doc_comment_decoration("///test");
-        assert_eq!(stripped, "test".to_string());
+        assert_eq!(stripped, "test");
         let stripped = strip_doc_comment_decoration("///!test");
-        assert_eq!(stripped, "test".to_string());
+        assert_eq!(stripped, "test");
         let stripped = strip_doc_comment_decoration("//test");
-        assert_eq!(stripped, "test".to_string());
+        assert_eq!(stripped, "test");
     }
 }
index b282db5ba2b3fe37e818db7334b8b273dd8b5bd9..2a77e3e67915bb92b46fc42d20eced6281db784e 100644 (file)
@@ -265,7 +265,7 @@ pub fn name_from_to(&self, start: BytePos, end: BytePos) -> ast::Name {
     /// Calls `f` with a string slice of the source text spanning from `start`
     /// up to but excluding `end`.
     fn with_str_from_to<T>(&self, start: BytePos, end: BytePos, f: |s: &str| -> T) -> T {
-        f(self.filemap.src.as_slice().slice(
+        f(self.filemap.src.slice(
                 self.byte_offset(start).to_uint(),
                 self.byte_offset(end).to_uint()))
     }
@@ -321,7 +321,6 @@ pub fn bump(&mut self) {
             let last_char = self.curr.unwrap();
             let next = self.filemap
                           .src
-                          .as_slice()
                           .char_range_at(current_byte_offset);
             let byte_offset_diff = next.next - current_byte_offset;
             self.pos = self.pos + Pos::from_uint(byte_offset_diff);
@@ -343,7 +342,7 @@ pub fn bump(&mut self) {
     pub fn nextch(&self) -> Option<char> {
         let offset = self.byte_offset(self.pos).to_uint();
         if offset < self.filemap.src.len() {
-            Some(self.filemap.src.as_slice().char_at(offset))
+            Some(self.filemap.src.char_at(offset))
         } else {
             None
         }
@@ -764,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
@@ -797,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
@@ -805,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 8d0c2de048a5676bb2231a054c0c11ea3cf22783..951fe11a470bb5b28a0cc352f99984ff39d62f83 100644 (file)
@@ -954,7 +954,7 @@ fn string_to_tts_1 () {
             }\
         ]\
     }\
-]".to_string()
+]"
         );
     }
 
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 e9937dc9b60452b19c1c9b9116d3a959d587e2e6..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>,
@@ -2844,7 +2848,7 @@ pub fn print_comment(&mut self,
             comments::BlankLine => {
                 // We need to do at least one, possibly two hardbreaks.
                 let is_semi = match self.s.last_token() {
-                    pp::String(s, _) => ";" == s.as_slice(),
+                    pp::String(s, _) => ";" == s,
                     _ => false
                 };
                 if is_semi || self.is_begin() || self.is_end() {
@@ -2961,9 +2965,9 @@ fn test_fun_to_string() {
             variadic: false
         };
         let generics = ast_util::empty_generics();
-        assert_eq!(&fun_to_string(&decl, ast::NormalFn, abba_ident,
+        assert_eq!(fun_to_string(&decl, ast::NormalFn, abba_ident,
                                None, &generics),
-                   &"fn abba()".to_string());
+                   "fn abba()");
     }
 
     #[test]
@@ -2981,7 +2985,7 @@ fn test_variant_to_string() {
         });
 
         let varstr = variant_to_string(&var);
-        assert_eq!(&varstr,&"pub principal_skinner".to_string());
+        assert_eq!(varstr, "pub principal_skinner");
     }
 
     #[test]
index 05828fc05f8c60358bb05ae27e83c2e520605094..ca2f190ce76be103d77930c3cab5e1750fa0f4d1 100644 (file)
 use ptr::P;
 use util::small_vector::SmallVector;
 
+enum ShouldFail {
+    No,
+    Yes(Option<InternedString>),
+}
+
 struct Test {
     span: Span,
     path: Vec<ast::Ident> ,
     bench: bool,
     ignore: bool,
-    should_fail: bool
+    should_fail: ShouldFail
 }
 
 struct TestCtxt<'a> {
@@ -360,8 +365,16 @@ fn is_ignored(i: &ast::Item) -> bool {
     i.attrs.iter().any(|attr| attr.check_name("ignore"))
 }
 
-fn should_fail(i: &ast::Item) -> bool {
-    attr::contains_name(i.attrs.as_slice(), "should_fail")
+fn should_fail(i: &ast::Item) -> ShouldFail {
+    match i.attrs.iter().find(|attr| attr.check_name("should_fail")) {
+        Some(attr) => {
+            let msg = attr.meta_item_list()
+                .and_then(|list| list.iter().find(|mi| mi.check_name("expected")))
+                .and_then(|mi| mi.value_str());
+            ShouldFail::Yes(msg)
+        }
+        None => ShouldFail::No,
+    }
 }
 
 /*
@@ -550,7 +563,20 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
                                   vec![name_expr]);
 
     let ignore_expr = ecx.expr_bool(span, test.ignore);
-    let fail_expr = ecx.expr_bool(span, test.should_fail);
+    let should_fail_path = |name| {
+        ecx.path(span, vec![self_id, test_id, ecx.ident_of("ShouldFail"), ecx.ident_of(name)])
+    };
+    let fail_expr = match test.should_fail {
+        ShouldFail::No => ecx.expr_path(should_fail_path("No")),
+        ShouldFail::Yes(ref msg) => {
+            let path = should_fail_path("Yes");
+            let arg = match *msg {
+                Some(ref msg) => ecx.expr_some(span, ecx.expr_str(span, msg.clone())),
+                None => ecx.expr_none(span),
+            };
+            ecx.expr_call(span, ecx.expr_path(path), vec![arg])
+        }
+    };
 
     // self::test::TestDesc { ... }
     let desc_expr = ecx.expr_struct(
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 c1393767c8adcaf62af86f86b2f1e70452e9c64a..65f8415835a36ce58f0b254efffed8d9ab08fd1a 100644 (file)
@@ -183,7 +183,7 @@ pub fn new(out: T) -> Option<Box<Terminal<T>+Send+'static>> {
         let entry = open(term.as_slice());
         if entry.is_err() {
             if os::getenv("MSYSCON").map_or(false, |s| {
-                    "mintty.exe" == s.as_slice()
+                    "mintty.exe" == s
                 }) {
                 // msys terminal
                 return Some(box TerminfoTerminal {out: out,
index 3c909a3c708429ee34d969df83187911fb7e7b50..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 {
@@ -529,8 +537,7 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8> ,String> {
                     }
                 }
                 FormatHEX => {
-                    s = s.as_slice()
-                         .to_ascii()
+                    s = s.to_ascii()
                          .iter()
                          .map(|b| b.to_uppercase().as_byte())
                          .collect();
index 9eb7216fba0bfedea7a58cbdd764310a081b7ef9..9b5e6f5cc9f6ff54f2a90c15ae3da2c02655bf79 100644 (file)
@@ -218,8 +218,7 @@ macro_rules! try( ($e:expr) => (
         Err(_) => return Err("input not utf-8".to_string()),
     };
 
-    let term_names: Vec<String> = names_str.as_slice()
-                                           .split('|')
+    let term_names: Vec<String> = names_str.split('|')
                                            .map(|s| s.to_string())
                                            .collect();
 
index 94e234291af98fd664b362cdba4e8d505185c9bb..33bfd69f71bb8b9b7fe4b52f7c5e2f0969d91307 100644 (file)
@@ -37,7 +37,7 @@ pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> {
                 dirs_to_search.push(homedir.unwrap().join(".terminfo"))
             }
             match getenv("TERMINFO_DIRS") {
-                Some(dirs) => for i in dirs.as_slice().split(':') {
+                Some(dirs) => for i in dirs.split(':') {
                     if i == "" {
                         dirs_to_search.push(Path::new("/usr/share/terminfo"));
                     } else {
@@ -102,10 +102,10 @@ fn x(t: &str) -> String {
         let p = get_dbpath_for_term(t).expect("no terminfo entry found");
         p.as_str().unwrap().to_string()
     };
-    assert!(x("screen") == "/usr/share/terminfo/s/screen".to_string());
+    assert!(x("screen") == "/usr/share/terminfo/s/screen");
     assert!(get_dbpath_for_term("") == None);
     setenv("TERMINFO_DIRS", ":");
-    assert!(x("screen") == "/usr/share/terminfo/s/screen".to_string());
+    assert!(x("screen") == "/usr/share/terminfo/s/screen");
     unsetenv("TERMINFO_DIRS");
 }
 
index c943d8706e55b71cf96dc8018294bb25908bc559..ffc26738dd7b2d7ca23d73eb9f98d08e833751c8 100644 (file)
@@ -47,6 +47,7 @@
 use self::NamePadding::*;
 use self::OutputLocation::*;
 
+use std::any::{Any, AnyRefExt};
 use std::collections::TreeMap;
 use stats::Stats;
 use getopts::{OptGroup, optflag, optopt};
@@ -78,7 +79,7 @@ pub mod test {
              MetricChange, Improvement, Regression, LikelyNoise,
              StaticTestFn, StaticTestName, DynTestName, DynTestFn,
              run_test, test_main, test_main_static, filter_tests,
-             parse_opts, StaticBenchFn};
+             parse_opts, StaticBenchFn, ShouldFail};
 }
 
 pub mod stats;
@@ -108,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 {
@@ -178,19 +185,26 @@ 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(Copy, Clone, Show, PartialEq, Eq, Hash)]
+pub enum ShouldFail {
+    No,
+    Yes(Option<&'static str>)
+}
+
 // The definition of a single test. A test runner will run a list of
 // these.
 #[deriving(Clone, Show, PartialEq, Eq, Hash)]
 pub struct TestDesc {
     pub name: TestName,
     pub ignore: bool,
-    pub should_fail: bool,
+    pub should_fail: ShouldFail,
 }
 
 #[deriving(Show)]
@@ -205,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}
@@ -231,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
@@ -273,6 +291,8 @@ pub enum ColorConfig {
     NeverColor,
 }
 
+impl Copy for ColorConfig {}
+
 pub struct TestOpts {
     pub filter: Option<Regex>,
     pub run_ignored: bool,
@@ -346,7 +366,7 @@ fn optgroups() -> Vec<getopts::OptGroup> {
 
 fn usage(binary: &str) {
     let message = format!("Usage: {} [OPTIONS] [FILTER]", binary);
-    println!(r"{usage}
+    println!(r#"{usage}
 
 The FILTER regex is tested against the name of all tests to run, and
 only those tests that match are run.
@@ -366,10 +386,12 @@ fn usage(binary: &str) {
                      function takes one argument (test::Bencher).
     #[should_fail] - This function (also labeled with #[test]) will only pass if
                      the code causes a failure (an assertion failure or panic!)
+                     A message may be provided, which the failure string must
+                     contain: #[should_fail(expected = "foo")].
     #[ignore]      - When applied to a function which is already attributed as a
                      test, then the test runner will ignore these tests during
                      normal test runs. Running with --ignored will run these
-                     tests.",
+                     tests."#,
              usage = getopts::usage(message.as_slice(),
                                     optgroups().as_slice()));
 }
@@ -471,7 +493,7 @@ pub fn opt_shard(maybestr: Option<String>) -> Option<(uint,uint)> {
     match maybestr {
         None => None,
         Some(s) => {
-            let mut it = s.as_slice().split('.');
+            let mut it = s.split('.');
             match (it.next().and_then(from_str::<uint>), it.next().and_then(from_str::<uint>),
                    it.next()) {
                 (Some(a), Some(b), None) => {
@@ -706,7 +728,7 @@ pub fn write_failures(&mut self) -> io::IoResult<()> {
         }
 
         try!(self.write_plain("\nfailures:\n"));
-        failures.as_mut_slice().sort();
+        failures.sort();
         for name in failures.iter() {
             try!(self.write_plain(format!("    {}\n",
                                           name.as_slice()).as_slice()));
@@ -902,13 +924,13 @@ fn should_sort_failures_before_printing_them() {
     let test_a = TestDesc {
         name: StaticTestName("a"),
         ignore: false,
-        should_fail: false
+        should_fail: ShouldFail::No
     };
 
     let test_b = TestDesc {
         name: StaticTestName("b"),
         ignore: false,
-        should_fail: false
+        should_fail: ShouldFail::No
     };
 
     let mut st = ConsoleTestState {
@@ -934,8 +956,8 @@ fn should_sort_failures_before_printing_them() {
         Pretty(_) => unreachable!()
     };
 
-    let apos = s.as_slice().find_str("a").unwrap();
-    let bpos = s.as_slice().find_str("b").unwrap();
+    let apos = s.find_str("a").unwrap();
+    let bpos = s.find_str("b").unwrap();
     assert!(apos < bpos);
 }
 
@@ -1114,7 +1136,7 @@ fn run_test_inner(desc: TestDesc,
 
             let stdout = reader.read_to_end().unwrap().into_iter().collect();
             let task_result = result_future.into_inner();
-            let test_result = calc_result(&desc, task_result.is_ok());
+            let test_result = calc_result(&desc, task_result);
             monitor_ch.send((desc.clone(), test_result, stdout));
         })
     }
@@ -1126,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;
         }
@@ -1148,13 +1170,17 @@ fn run_test_inner(desc: TestDesc,
     }
 }
 
-fn calc_result(desc: &TestDesc, task_succeeded: bool) -> TestResult {
-    if task_succeeded {
-        if desc.should_fail { TrFailed }
-        else { TrOk }
-    } else {
-        if desc.should_fail { TrOk }
-        else { TrFailed }
+fn calc_result(desc: &TestDesc, task_result: Result<(), Box<Any+Send>>) -> TestResult {
+    match (&desc.should_fail, task_result) {
+        (&ShouldFail::No, Ok(())) |
+        (&ShouldFail::Yes(None), Err(_)) => TrOk,
+        (&ShouldFail::Yes(Some(msg)), Err(ref err))
+            if err.downcast_ref::<String>()
+                .map(|e| &**e)
+                .or_else(|| err.downcast_ref::<&'static str>().map(|e| *e))
+                .map(|e| e.contains(msg))
+                .unwrap_or(false) => TrOk,
+        _ => TrFailed,
     }
 }
 
@@ -1437,7 +1463,7 @@ mod tests {
                TestDesc, TestDescAndFn, TestOpts, run_test,
                Metric, MetricMap, MetricAdded, MetricRemoved,
                Improvement, Regression, LikelyNoise,
-               StaticTestName, DynTestName, DynTestFn};
+               StaticTestName, DynTestName, DynTestFn, ShouldFail};
     use std::io::TempDir;
 
     #[test]
@@ -1447,7 +1473,7 @@ pub fn do_not_run_ignored_tests() {
             desc: TestDesc {
                 name: StaticTestName("whatever"),
                 ignore: true,
-                should_fail: false
+                should_fail: ShouldFail::No,
             },
             testfn: DynTestFn(proc() f()),
         };
@@ -1464,7 +1490,7 @@ fn f() { }
             desc: TestDesc {
                 name: StaticTestName("whatever"),
                 ignore: true,
-                should_fail: false
+                should_fail: ShouldFail::No,
             },
             testfn: DynTestFn(proc() f()),
         };
@@ -1481,7 +1507,24 @@ fn test_should_fail() {
             desc: TestDesc {
                 name: StaticTestName("whatever"),
                 ignore: false,
-                should_fail: true
+                should_fail: ShouldFail::Yes(None)
+            },
+            testfn: DynTestFn(proc() f()),
+        };
+        let (tx, rx) = channel();
+        run_test(&TestOpts::new(), false, desc, tx);
+        let (_, res, _) = rx.recv();
+        assert!(res == TrOk);
+    }
+
+    #[test]
+    fn test_should_fail_good_message() {
+        fn f() { panic!("an error message"); }
+        let desc = TestDescAndFn {
+            desc: TestDesc {
+                name: StaticTestName("whatever"),
+                ignore: false,
+                should_fail: ShouldFail::Yes(Some("error message"))
             },
             testfn: DynTestFn(proc() f()),
         };
@@ -1491,6 +1534,23 @@ fn test_should_fail() {
         assert!(res == TrOk);
     }
 
+    #[test]
+    fn test_should_fail_bad_message() {
+        fn f() { panic!("an error message"); }
+        let desc = TestDescAndFn {
+            desc: TestDesc {
+                name: StaticTestName("whatever"),
+                ignore: false,
+                should_fail: ShouldFail::Yes(Some("foobar"))
+            },
+            testfn: DynTestFn(proc() f()),
+        };
+        let (tx, rx) = channel();
+        run_test(&TestOpts::new(), false, desc, tx);
+        let (_, res, _) = rx.recv();
+        assert!(res == TrFailed);
+    }
+
     #[test]
     fn test_should_fail_but_succeeds() {
         fn f() { }
@@ -1498,7 +1558,7 @@ fn f() { }
             desc: TestDesc {
                 name: StaticTestName("whatever"),
                 ignore: false,
-                should_fail: true
+                should_fail: ShouldFail::Yes(None)
             },
             testfn: DynTestFn(proc() f()),
         };
@@ -1544,7 +1604,7 @@ pub fn filter_for_ignored_option() {
                 desc: TestDesc {
                     name: StaticTestName("1"),
                     ignore: true,
-                    should_fail: false,
+                    should_fail: ShouldFail::No,
                 },
                 testfn: DynTestFn(proc() {}),
             },
@@ -1552,7 +1612,7 @@ pub fn filter_for_ignored_option() {
                 desc: TestDesc {
                     name: StaticTestName("2"),
                     ignore: false,
-                    should_fail: false
+                    should_fail: ShouldFail::No,
                 },
                 testfn: DynTestFn(proc() {}),
             });
@@ -1560,7 +1620,7 @@ pub fn filter_for_ignored_option() {
 
         assert_eq!(filtered.len(), 1);
         assert_eq!(filtered[0].desc.name.to_string(),
-                   "1".to_string());
+                   "1");
         assert!(filtered[0].desc.ignore == false);
     }
 
@@ -1588,7 +1648,7 @@ fn testfn() { }
                     desc: TestDesc {
                         name: DynTestName((*name).clone()),
                         ignore: false,
-                        should_fail: false
+                        should_fail: ShouldFail::No,
                     },
                     testfn: DynTestFn(testfn),
                 };
@@ -1629,7 +1689,7 @@ fn test_fn() {}
                 desc: TestDesc {
                     name: DynTestName(name.to_string()),
                     ignore: false,
-                    should_fail: false
+                    should_fail: ShouldFail::No,
                 },
                 testfn: DynTestFn(test_fn)
             }
index c157fb10bd4a7d8167cd274858f5d09369e9ff24..f9e6907f0e880d4be5aad6b342fa938c9b5ff777 100644 (file)
@@ -250,7 +250,7 @@ fn median_abs_dev(&self) -> T {
         // This constant is derived by smarter statistics brains than me, but it is
         // consistent with how R and other packages treat the MAD.
         let number = FromPrimitive::from_f64(1.4826).unwrap();
-        abs_devs.as_slice().median() * number
+        abs_devs.median() * number
     }
 
     fn median_abs_dev_pct(&self) -> T {
index 06a0df852b93623e24db19a3090ddb493d050121..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 {
@@ -1564,8 +1574,8 @@ fn test_asctime() {
 
         debug!("test_ctime: {} {}", utc.asctime(), local.asctime());
 
-        assert_eq!(utc.asctime().to_string(), "Fri Feb 13 23:31:30 2009".to_string());
-        assert_eq!(local.asctime().to_string(), "Fri Feb 13 15:31:30 2009".to_string());
+        assert_eq!(utc.asctime().to_string(), "Fri Feb 13 23:31:30 2009");
+        assert_eq!(local.asctime().to_string(), "Fri Feb 13 15:31:30 2009");
     }
 
     fn test_ctime() {
@@ -1577,8 +1587,8 @@ fn test_ctime() {
 
         debug!("test_ctime: {} {}", utc.ctime(), local.ctime());
 
-        assert_eq!(utc.ctime().to_string(), "Fri Feb 13 15:31:30 2009".to_string());
-        assert_eq!(local.ctime().to_string(), "Fri Feb 13 15:31:30 2009".to_string());
+        assert_eq!(utc.ctime().to_string(), "Fri Feb 13 15:31:30 2009");
+        assert_eq!(local.ctime().to_string(), "Fri Feb 13 15:31:30 2009");
     }
 
     fn test_strftime() {
@@ -1588,56 +1598,56 @@ fn test_strftime() {
         let utc = at_utc(time);
         let local = at(time);
 
-        assert_eq!(local.strftime("").unwrap().to_string(), "".to_string());
-        assert_eq!(local.strftime("%A").unwrap().to_string(), "Friday".to_string());
-        assert_eq!(local.strftime("%a").unwrap().to_string(), "Fri".to_string());
-        assert_eq!(local.strftime("%B").unwrap().to_string(), "February".to_string());
-        assert_eq!(local.strftime("%b").unwrap().to_string(), "Feb".to_string());
-        assert_eq!(local.strftime("%C").unwrap().to_string(), "20".to_string());
+        assert_eq!(local.strftime("").unwrap().to_string(), "");
+        assert_eq!(local.strftime("%A").unwrap().to_string(), "Friday");
+        assert_eq!(local.strftime("%a").unwrap().to_string(), "Fri");
+        assert_eq!(local.strftime("%B").unwrap().to_string(), "February");
+        assert_eq!(local.strftime("%b").unwrap().to_string(), "Feb");
+        assert_eq!(local.strftime("%C").unwrap().to_string(), "20");
         assert_eq!(local.strftime("%c").unwrap().to_string(),
-                   "Fri Feb 13 15:31:30 2009".to_string());
-        assert_eq!(local.strftime("%D").unwrap().to_string(), "02/13/09".to_string());
-        assert_eq!(local.strftime("%d").unwrap().to_string(), "13".to_string());
-        assert_eq!(local.strftime("%e").unwrap().to_string(), "13".to_string());
-        assert_eq!(local.strftime("%F").unwrap().to_string(), "2009-02-13".to_string());
-        assert_eq!(local.strftime("%f").unwrap().to_string(), "000054321".to_string());
-        assert_eq!(local.strftime("%G").unwrap().to_string(), "2009".to_string());
-        assert_eq!(local.strftime("%g").unwrap().to_string(), "09".to_string());
-        assert_eq!(local.strftime("%H").unwrap().to_string(), "15".to_string());
-        assert_eq!(local.strftime("%h").unwrap().to_string(), "Feb".to_string());
-        assert_eq!(local.strftime("%I").unwrap().to_string(), "03".to_string());
-        assert_eq!(local.strftime("%j").unwrap().to_string(), "044".to_string());
-        assert_eq!(local.strftime("%k").unwrap().to_string(), "15".to_string());
-        assert_eq!(local.strftime("%l").unwrap().to_string(), " 3".to_string());
-        assert_eq!(local.strftime("%M").unwrap().to_string(), "31".to_string());
-        assert_eq!(local.strftime("%m").unwrap().to_string(), "02".to_string());
-        assert_eq!(local.strftime("%n").unwrap().to_string(), "\n".to_string());
-        assert_eq!(local.strftime("%P").unwrap().to_string(), "pm".to_string());
-        assert_eq!(local.strftime("%p").unwrap().to_string(), "PM".to_string());
-        assert_eq!(local.strftime("%R").unwrap().to_string(), "15:31".to_string());
-        assert_eq!(local.strftime("%r").unwrap().to_string(), "03:31:30 PM".to_string());
-        assert_eq!(local.strftime("%S").unwrap().to_string(), "30".to_string());
-        assert_eq!(local.strftime("%s").unwrap().to_string(), "1234567890".to_string());
-        assert_eq!(local.strftime("%T").unwrap().to_string(), "15:31:30".to_string());
-        assert_eq!(local.strftime("%t").unwrap().to_string(), "\t".to_string());
-        assert_eq!(local.strftime("%U").unwrap().to_string(), "06".to_string());
-        assert_eq!(local.strftime("%u").unwrap().to_string(), "5".to_string());
-        assert_eq!(local.strftime("%V").unwrap().to_string(), "07".to_string());
-        assert_eq!(local.strftime("%v").unwrap().to_string(), "13-Feb-2009".to_string());
-        assert_eq!(local.strftime("%W").unwrap().to_string(), "06".to_string());
-        assert_eq!(local.strftime("%w").unwrap().to_string(), "5".to_string());
+                   "Fri Feb 13 15:31:30 2009");
+        assert_eq!(local.strftime("%D").unwrap().to_string(), "02/13/09");
+        assert_eq!(local.strftime("%d").unwrap().to_string(), "13");
+        assert_eq!(local.strftime("%e").unwrap().to_string(), "13");
+        assert_eq!(local.strftime("%F").unwrap().to_string(), "2009-02-13");
+        assert_eq!(local.strftime("%f").unwrap().to_string(), "000054321");
+        assert_eq!(local.strftime("%G").unwrap().to_string(), "2009");
+        assert_eq!(local.strftime("%g").unwrap().to_string(), "09");
+        assert_eq!(local.strftime("%H").unwrap().to_string(), "15");
+        assert_eq!(local.strftime("%h").unwrap().to_string(), "Feb");
+        assert_eq!(local.strftime("%I").unwrap().to_string(), "03");
+        assert_eq!(local.strftime("%j").unwrap().to_string(), "044");
+        assert_eq!(local.strftime("%k").unwrap().to_string(), "15");
+        assert_eq!(local.strftime("%l").unwrap().to_string(), " 3");
+        assert_eq!(local.strftime("%M").unwrap().to_string(), "31");
+        assert_eq!(local.strftime("%m").unwrap().to_string(), "02");
+        assert_eq!(local.strftime("%n").unwrap().to_string(), "\n");
+        assert_eq!(local.strftime("%P").unwrap().to_string(), "pm");
+        assert_eq!(local.strftime("%p").unwrap().to_string(), "PM");
+        assert_eq!(local.strftime("%R").unwrap().to_string(), "15:31");
+        assert_eq!(local.strftime("%r").unwrap().to_string(), "03:31:30 PM");
+        assert_eq!(local.strftime("%S").unwrap().to_string(), "30");
+        assert_eq!(local.strftime("%s").unwrap().to_string(), "1234567890");
+        assert_eq!(local.strftime("%T").unwrap().to_string(), "15:31:30");
+        assert_eq!(local.strftime("%t").unwrap().to_string(), "\t");
+        assert_eq!(local.strftime("%U").unwrap().to_string(), "06");
+        assert_eq!(local.strftime("%u").unwrap().to_string(), "5");
+        assert_eq!(local.strftime("%V").unwrap().to_string(), "07");
+        assert_eq!(local.strftime("%v").unwrap().to_string(), "13-Feb-2009");
+        assert_eq!(local.strftime("%W").unwrap().to_string(), "06");
+        assert_eq!(local.strftime("%w").unwrap().to_string(), "5");
         // FIXME (#2350): support locale
-        assert_eq!(local.strftime("%X").unwrap().to_string(), "15:31:30".to_string());
+        assert_eq!(local.strftime("%X").unwrap().to_string(), "15:31:30");
         // FIXME (#2350): support locale
-        assert_eq!(local.strftime("%x").unwrap().to_string(), "02/13/09".to_string());
-        assert_eq!(local.strftime("%Y").unwrap().to_string(), "2009".to_string());
-        assert_eq!(local.strftime("%y").unwrap().to_string(), "09".to_string());
+        assert_eq!(local.strftime("%x").unwrap().to_string(), "02/13/09");
+        assert_eq!(local.strftime("%Y").unwrap().to_string(), "2009");
+        assert_eq!(local.strftime("%y").unwrap().to_string(), "09");
         // FIXME (#2350): support locale
-        assert_eq!(local.strftime("%Z").unwrap().to_string(), "".to_string());
-        assert_eq!(local.strftime("%z").unwrap().to_string(), "-0800".to_string());
+        assert_eq!(local.strftime("%Z").unwrap().to_string(), "");
+        assert_eq!(local.strftime("%z").unwrap().to_string(), "-0800");
         assert_eq!(local.strftime("%+").unwrap().to_string(),
-                   "2009-02-13T15:31:30-08:00".to_string());
-        assert_eq!(local.strftime("%%").unwrap().to_string(), "%".to_string());
+                   "2009-02-13T15:31:30-08:00");
+        assert_eq!(local.strftime("%%").unwrap().to_string(), "%");
 
          let invalid_specifiers = ["%E", "%J", "%K", "%L", "%N", "%O", "%o", "%Q", "%q"];
         for &sp in invalid_specifiers.iter() {
@@ -1646,16 +1656,16 @@ fn test_strftime() {
         assert_eq!(local.strftime("%").unwrap_err(), MissingFormatConverter);
         assert_eq!(local.strftime("%A %").unwrap_err(), MissingFormatConverter);
 
-        assert_eq!(local.asctime().to_string(), "Fri Feb 13 15:31:30 2009".to_string());
-        assert_eq!(local.ctime().to_string(), "Fri Feb 13 15:31:30 2009".to_string());
-        assert_eq!(local.rfc822z().to_string(), "Fri, 13 Feb 2009 15:31:30 -0800".to_string());
-        assert_eq!(local.rfc3339().to_string(), "2009-02-13T15:31:30-08:00".to_string());
+        assert_eq!(local.asctime().to_string(), "Fri Feb 13 15:31:30 2009");
+        assert_eq!(local.ctime().to_string(), "Fri Feb 13 15:31:30 2009");
+        assert_eq!(local.rfc822z().to_string(), "Fri, 13 Feb 2009 15:31:30 -0800");
+        assert_eq!(local.rfc3339().to_string(), "2009-02-13T15:31:30-08:00");
 
-        assert_eq!(utc.asctime().to_string(), "Fri Feb 13 23:31:30 2009".to_string());
-        assert_eq!(utc.ctime().to_string(), "Fri Feb 13 15:31:30 2009".to_string());
-        assert_eq!(utc.rfc822().to_string(), "Fri, 13 Feb 2009 23:31:30 GMT".to_string());
-        assert_eq!(utc.rfc822z().to_string(), "Fri, 13 Feb 2009 23:31:30 -0000".to_string());
-        assert_eq!(utc.rfc3339().to_string(), "2009-02-13T23:31:30Z".to_string());
+        assert_eq!(utc.asctime().to_string(), "Fri Feb 13 23:31:30 2009");
+        assert_eq!(utc.ctime().to_string(), "Fri Feb 13 15:31:30 2009");
+        assert_eq!(utc.rfc822().to_string(), "Fri, 13 Feb 2009 23:31:30 GMT");
+        assert_eq!(utc.rfc822z().to_string(), "Fri, 13 Feb 2009 23:31:30 -0000");
+        assert_eq!(utc.rfc3339().to_string(), "2009-02-13T23:31:30Z");
     }
 
     fn test_timespec_eq_ord() {
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 94a168a74ebb572972aa570ec3edd2ddcd761957..8a2c2d35ef5ba9eba7ff6147ca422c01e608d1fc 100644 (file)
@@ -41,20 +41,6 @@ pub fn bar() {
              static __STATIC_FMTSTR: &'static [&'static str] =
                  (&([("test" as &'static str)] as [&'static str, ..1]) as
                      &'static [&'static str, ..1]);
-             let __args_vec =
-                 (&([] as [core::fmt::Argument<'_>, ..0]) as
-                     &[core::fmt::Argument<'_>, ..0]);
-             let __args =
-                 (unsafe {
-                      ((::std::fmt::Arguments::new as
-                           unsafe fn(&'static [&'static str], &'a [core::fmt::Argument<'a>]) -> core::fmt::Arguments<'a>)((__STATIC_FMTSTR
-                                                                                                                              as
-                                                                                                                              &'static [&'static str]),
-                                                                                                                          (__args_vec
-                                                                                                                              as
-                                                                                                                              &[core::fmt::Argument<'_>, ..0]))
-                          as core::fmt::Arguments<'_>)
-                  } as core::fmt::Arguments<'_>);
 
 
 
@@ -64,7 +50,16 @@ pub fn bar() {
 
 
              ((::std::fmt::format as
-                  fn(&core::fmt::Arguments<'_>) -> collections::string::String)((&(__args
+                  fn(&core::fmt::Arguments<'_>) -> collections::string::String)((&((::std::fmt::Arguments::new
+                                                                                       as
+                                                                                       fn(&'a [&'a str], &'a [core::fmt::Argument<'a>]) -> core::fmt::Arguments<'a>)((__STATIC_FMTSTR
+                                                                                                                                                                         as
+                                                                                                                                                                         &'static [&'static str]),
+                                                                                                                                                                     (&([]
+                                                                                                                                                                           as
+                                                                                                                                                                           [core::fmt::Argument<'_>, ..0])
+                                                                                                                                                                         as
+                                                                                                                                                                         &[core::fmt::Argument<'_>, ..0]))
                                                                                       as
                                                                                       core::fmt::Arguments<'_>)
                                                                                     as
diff --git a/src/test/run-fail/test-should-fail-bad-message.rs b/src/test/run-fail/test-should-fail-bad-message.rs
new file mode 100644 (file)
index 0000000..76a5022
--- /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.
+
+// check-stdout
+// error-pattern:task 'test_foo' panicked at
+// compile-flags: --test
+// ignore-pretty: does not work well with `--test`
+
+#[test]
+#[should_fail(expected = "foobar")]
+fn test_foo() {
+    panic!("blah")
+}
+
+
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)
diff --git a/src/test/run-pass/test-should-fail-good-message.rs b/src/test/run-pass/test-should-fail-good-message.rs
new file mode 100644 (file)
index 0000000..dcb2fe6
--- /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.
+
+// compile-flags: --test
+// ignore-pretty: does not work well with `--test`
+
+#[test]
+#[should_fail(expected = "foo")]
+fn test_foo() {
+    panic!("foo bar")
+}
+
+#[test]
+#[should_fail(expected = "foo")]
+fn test_foo_dynamic() {
+    panic!("{} bar", "foo")
+}
+
+
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
 }